From 25fde2d0921267c56dbe5349d49fd06ad9ccb002 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Thu, 13 Jan 2005 18:23:34 -0800 Subject: [PATCH 01/83] In TRADITIONAL mode, don't allow a NOT NULL field with no default be set to DEFAULT (with no argument) or to the field's type's default by not being listed in the list of fields being inserted. (Bug #5986) --- mysql-test/r/strict.result | 37 +++++++++++++++++++++++++++++++++++++ mysql-test/t/strict.test | 34 ++++++++++++++++++++++++++++++++++ sql/item.cc | 22 ++++++++++++++++++++++ sql/item.h | 10 +--------- sql/sql_insert.cc | 3 ++- 5 files changed, 96 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index fb228d37da3..45f7caa0b11 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -921,3 +921,40 @@ col1 col2 3 99 DROP TABLE t1; +SET @@sql_mode = 'traditional'; +CREATE TABLE t1 (i int not null); +INSERT INTO t1 VALUES (); +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT); +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT(i)); +ERROR HY000: Field 'i' doesn't have a default value +ALTER TABLE t1 ADD j int; +INSERT INTO t1 SET j = 1; +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 SET j = 1, i = DEFAULT; +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 SET j = 1, i = DEFAULT(i); +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT,1); +ERROR HY000: Field 'i' doesn't have a default value +DROP TABLE t1; +SET @@sql_mode = ''; +CREATE TABLE t1 (i int not null); +INSERT INTO t1 VALUES (); +INSERT INTO t1 VALUES (DEFAULT); +Warnings: +Warning 1364 Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT(i)); +ERROR HY000: Field 'i' doesn't have a default value +ALTER TABLE t1 ADD j int; +INSERT INTO t1 SET j = 1; +INSERT INTO t1 SET j = 1, i = DEFAULT; +Warnings: +Warning 1364 Field 'i' doesn't have a default value +INSERT INTO t1 SET j = 1, i = DEFAULT(i); +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT,1); +Warnings: +Warning 1364 Field 'i' doesn't have a default value +DROP TABLE t1; diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index a0cfc0c60f4..ba8fafe3fdd 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -638,3 +638,37 @@ INSERT IGNORE INTO t1 (col1) values (3); INSERT IGNORE INTO t1 () values (); SELECT * FROM t1; DROP TABLE t1; + +# Test fields with no default value that are NOT NULL (Bug #5986) +SET @@sql_mode = 'traditional'; +CREATE TABLE t1 (i int not null); +--error 1364 +INSERT INTO t1 VALUES (); +--error 1364 +INSERT INTO t1 VALUES (DEFAULT); +--error 1364 +INSERT INTO t1 VALUES (DEFAULT(i)); +ALTER TABLE t1 ADD j int; +--error 1364 +INSERT INTO t1 SET j = 1; +--error 1364 +INSERT INTO t1 SET j = 1, i = DEFAULT; +--error 1364 +INSERT INTO t1 SET j = 1, i = DEFAULT(i); +--error 1364 +INSERT INTO t1 VALUES (DEFAULT,1); +DROP TABLE t1; +SET @@sql_mode = ''; +CREATE TABLE t1 (i int not null); +INSERT INTO t1 VALUES (); +INSERT INTO t1 VALUES (DEFAULT); +# DEFAULT(i) is an error even with the default sql_mode +--error 1364 +INSERT INTO t1 VALUES (DEFAULT(i)); +ALTER TABLE t1 ADD j int; +INSERT INTO t1 SET j = 1; +INSERT INTO t1 SET j = 1, i = DEFAULT; +--error 1364 +INSERT INTO t1 SET j = 1, i = DEFAULT(i); +INSERT INTO t1 VALUES (DEFAULT,1); +DROP TABLE t1; diff --git a/sql/item.cc b/sql/item.cc index c84496f8eb7..a82037c3762 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3204,6 +3204,7 @@ bool Item_default_value::fix_fields(THD *thd, return FALSE; } + void Item_default_value::print(String *str) { if (!arg) @@ -3216,6 +3217,27 @@ void Item_default_value::print(String *str) str->append(')'); } + +int Item_default_value::save_in_field(Field *field_arg, bool no_conversions) +{ + if (!arg) + { + if (field_arg->flags & NO_DEFAULT_VALUE_FLAG) + { + push_warning_printf(field_arg->table->in_use, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_NO_DEFAULT_FOR_FIELD, + ER(ER_NO_DEFAULT_FOR_FIELD), + field_arg->field_name); + return 1; + } + field_arg->set_default(); + return 0; + } + return Item_field::save_in_field(field_arg, no_conversions); +} + + bool Item_insert_value::eq(const Item *item, bool binary_cmp) const { return item->type() == INSERT_VALUE_ITEM && diff --git a/sql/item.h b/sql/item.h index 2503f137355..b4386edeabc 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1316,15 +1316,7 @@ public: bool eq(const Item *item, bool binary_cmp) const; bool fix_fields(THD *, struct st_table_list *, Item **); void print(String *str); - int save_in_field(Field *field_arg, bool no_conversions) - { - if (!arg) - { - field_arg->set_default(); - return 0; - } - return Item_field::save_in_field(field_arg, no_conversions); - } + int save_in_field(Field *field_arg, bool no_conversions); table_map used_tables() const { return (table_map)0L; } bool walk(Item_processor processor, byte *args) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index ceb31f76953..d93010d9915 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -311,7 +311,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))); - if (fields.elements && check_that_all_fields_are_given_values(thd, table)) + if ((fields.elements || !value_count) && + check_that_all_fields_are_given_values(thd, table)) { /* thd->net.report_error is now set, which will abort the next loop */ error= 1; From 01ddc370f0eda1f605ca8be426f86acef9722ff1 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Fri, 14 Jan 2005 17:09:35 -0800 Subject: [PATCH 02/83] Enable warnings for 'no default' fields being set to default when they are not specified in an insert. Most of these changes are actually to clean up the test suite to either specify defaults to avoid warnings, or add the warnings to the results. Related to bug #5986. --- mysql-test/r/create.result | 4 ++++ mysql-test/r/ctype_latin1_de.result | 4 ++-- mysql-test/r/ctype_many.result | 16 ++++++++-------- mysql-test/r/gis-rtree.result | 1 - mysql-test/r/grant.result | 4 ++++ mysql-test/r/grant2.result | 4 ++++ mysql-test/r/help.result | 16 ++++++++++++++++ mysql-test/r/limit.result | 2 +- mysql-test/r/null.result | 2 +- mysql-test/r/order_by.result | 2 +- mysql-test/r/rpl000001.result | 4 ++++ mysql-test/r/sp.result | 6 +++--- mysql-test/r/strict.result | 8 ++++++++ mysql-test/r/type_blob.result | 2 +- mysql-test/r/type_ranges.result | 8 ++++---- mysql-test/r/warnings.result | 2 ++ mysql-test/t/ctype_latin1_de.test | 2 +- mysql-test/t/ctype_many.test | 6 +++--- mysql-test/t/gis-rtree.test | 1 - mysql-test/t/index_merge_ror.test | 12 ++++++------ mysql-test/t/limit.test | 2 +- mysql-test/t/null.test | 2 +- mysql-test/t/order_by.test | 2 +- mysql-test/t/show_check.test | 8 ++++---- mysql-test/t/sp.test | 2 +- mysql-test/t/type_blob.test | 2 +- mysql-test/t/type_ranges.test | 8 ++++---- sql/sql_insert.cc | 13 +++++++------ 28 files changed, 93 insertions(+), 52 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index f2e91c36f75..0082feeb67b 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -255,11 +255,15 @@ drop table t1; create table t1 (a int not null, b int, primary key (a)); insert into t1 values (1,1); create table if not exists t1 select 2; +Warnings: +Warning 1364 Field 'a' doesn't have a default value select * from t1; a b 1 1 0 2 create table if not exists t1 select 3 as 'a',4 as 'b'; +Warnings: +Warning 1364 Field 'a' doesn't have a default value create table if not exists t1 select 3 as 'a',3 as 'b'; ERROR 23000: Duplicate entry '3' for key 1 select * from t1; diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result index f890250e0a3..055b36c0daf 100644 --- a/mysql-test/r/ctype_latin1_de.result +++ b/mysql-test/r/ctype_latin1_de.result @@ -220,12 +220,12 @@ select * from t1 where match a against ("te*" in boolean mode)+0; a test drop table t1; -create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word)); +create table t1 (word varchar(255) not null, word2 varchar(255) not null default '', index(word)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `word` varchar(255) collate latin1_german2_ci NOT NULL, - `word2` varchar(255) collate latin1_german2_ci NOT NULL, + `word2` varchar(255) collate latin1_german2_ci NOT NULL default '', KEY `word` (`word`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae'); diff --git a/mysql-test/r/ctype_many.result b/mysql-test/r/ctype_many.result index 5932bd75787..87b83acfe0f 100644 --- a/mysql-test/r/ctype_many.result +++ b/mysql-test/r/ctype_many.result @@ -2,27 +2,27 @@ DROP TABLE IF EXISTS t1; SET CHARACTER SET latin1; CREATE TABLE t1 ( comment CHAR(32) ASCII NOT NULL, -koi8_ru_f CHAR(32) CHARACTER SET koi8r NOT NULL +koi8_ru_f CHAR(32) CHARACTER SET koi8r NOT NULL default '' ) CHARSET=latin5; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `comment` char(32) character set latin1 NOT NULL, - `koi8_ru_f` char(32) character set koi8r NOT NULL + `koi8_ru_f` char(32) character set koi8r NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin5 ALTER TABLE t1 CHANGE comment comment CHAR(32) CHARACTER SET latin2 NOT NULL; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `comment` char(32) character set latin2 NOT NULL, - `koi8_ru_f` char(32) character set koi8r NOT NULL + `koi8_ru_f` char(32) character set koi8r NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin5 ALTER TABLE t1 ADD latin5_f CHAR(32) NOT NULL; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `comment` char(32) character set latin2 NOT NULL, - `koi8_ru_f` char(32) character set koi8r NOT NULL, + `koi8_ru_f` char(32) character set koi8r NOT NULL default '', `latin5_f` char(32) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin5 ALTER TABLE t1 DEFAULT CHARSET=latin2; @@ -31,7 +31,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `comment` char(32) NOT NULL, - `koi8_ru_f` char(32) character set koi8r NOT NULL, + `koi8_ru_f` char(32) character set koi8r NOT NULL default '', `latin5_f` char(32) character set latin5 NOT NULL, `latin2_f` char(32) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin2 @@ -40,7 +40,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `comment` char(32) NOT NULL, - `koi8_ru_f` char(32) character set koi8r NOT NULL + `koi8_ru_f` char(32) character set koi8r NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin2 INSERT INTO t1 (koi8_ru_f,comment) VALUES ('a','LAT SMALL A'); INSERT INTO t1 (koi8_ru_f,comment) VALUES ('b','LAT SMALL B'); @@ -219,7 +219,7 @@ z LAT CAPIT Z 2 э CYR CAPIT E 2 ю CYR CAPIT YU 2 я CYR CAPIT YA 2 -ALTER TABLE t1 ADD utf8_f CHAR(32) CHARACTER SET utf8 NOT NULL; +ALTER TABLE t1 ADD utf8_f CHAR(32) CHARACTER SET utf8 NOT NULL default ''; UPDATE t1 SET utf8_f=CONVERT(koi8_ru_f USING utf8); SET CHARACTER SET koi8r; SELECT * FROM t1; @@ -340,7 +340,7 @@ CYR CAPIT SOFT SIGN CYR CAPIT E CYR CAPIT YU CYR CAPIT YA -ALTER TABLE t1 ADD bin_f CHAR(32) BYTE NOT NULL; +ALTER TABLE t1 ADD bin_f CHAR(32) BYTE NOT NULL default ''; UPDATE t1 SET bin_f=koi8_ru_f; SELECT COUNT(DISTINCT bin_f),COUNT(DISTINCT koi8_ru_f),COUNT(DISTINCT utf8_f) FROM t1; COUNT(DISTINCT bin_f) COUNT(DISTINCT koi8_ru_f) COUNT(DISTINCT utf8_f) diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index efd3b0f8e15..0e558e47594 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -758,7 +758,6 @@ SPATIAL KEY(g) INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText('LineString(1 2, 2 4)')); drop table t1; CREATE TABLE t1 ( -geoobjid INT NOT NULL, line LINESTRING NOT NULL, kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po', name VARCHAR(32), diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index e5f7f535ae2..2eaf30f802d 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -157,6 +157,10 @@ select 1; 1 1 insert into mysql.user (host, user) values ('localhost', 'test11'); +Warnings: +Warning 1364 Field 'ssl_cipher' doesn't have a default value +Warning 1364 Field 'x509_issuer' doesn't have a default value +Warning 1364 Field 'x509_subject' doesn't have a default value insert into mysql.db (host, db, user, select_priv) values ('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); alter table mysql.db order by db asc; diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 0779e2adfa2..dedf5935743 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -225,6 +225,10 @@ host user password % mysqltest_2 *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 localhost mysqltest_3 insert into mysql.user set host='%', user='mysqltest_B'; +Warnings: +Warning 1364 Field 'ssl_cipher' doesn't have a default value +Warning 1364 Field 'x509_issuer' doesn't have a default value +Warning 1364 Field 'x509_subject' doesn't have a default value create user mysqltest_A@'%'; ERROR 42000: Access denied for user 'mysqltest_3'@'localhost' to database 'mysql' rename user mysqltest_B@'%' to mysqltest_C@'%'; diff --git a/mysql-test/r/help.result b/mysql-test/r/help.result index edf7d0e91cb..85ca832828d 100644 --- a/mysql-test/r/help.result +++ b/mysql-test/r/help.result @@ -1,32 +1,48 @@ insert into mysql.help_category(help_category_id,name)values(1,'impossible_category_1'); +Warnings: +Warning 1364 Field 'url' doesn't have a default value select @category1_id:= 1; @category1_id:= 1 1 insert into mysql.help_category(help_category_id,name)values(2,'impossible_category_2'); +Warnings: +Warning 1364 Field 'url' doesn't have a default value select @category2_id:= 2; @category2_id:= 2 2 insert into mysql.help_category(help_category_id,name,parent_category_id)values(3,'impossible_category_3',@category2_id); +Warnings: +Warning 1364 Field 'url' doesn't have a default value select @category3_id:= 3; @category3_id:= 3 3 insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(1,'impossible_function_1',@category1_id,'description of \n impossible_function1\n','example of \n impossible_function1'); +Warnings: +Warning 1364 Field 'url' doesn't have a default value select @topic1_id:= 1; @topic1_id:= 1 1 insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(2,'impossible_function_2',@category1_id,'description of \n impossible_function2\n','example of \n impossible_function2'); +Warnings: +Warning 1364 Field 'url' doesn't have a default value select @topic2_id:= 2; @topic2_id:= 2 2 insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(3,'impossible_function_3',@category2_id,'description of \n impossible_function3\n','example of \n impossible_function3'); +Warnings: +Warning 1364 Field 'url' doesn't have a default value select @topic3_id:= 3; @topic3_id:= 3 3 insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(4,'impossible_function_4',@category2_id,'description of \n impossible_function4\n','example of \n impossible_function4'); +Warnings: +Warning 1364 Field 'url' doesn't have a default value select @topic4_id:= 4; @topic4_id:= 4 4 insert into mysql.help_topic(help_topic_id,name,help_category_id,description,example)values(5,'impossible_function_7',@category3_id,'description of \n impossible_function5\n','example of \n impossible_function7'); +Warnings: +Warning 1364 Field 'url' doesn't have a default value select @topic5_id:= 5; @topic5_id:= 5 5 diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result index c82105e6a49..8d20a191f1c 100644 --- a/mysql-test/r/limit.result +++ b/mysql-test/r/limit.result @@ -1,5 +1,5 @@ drop table if exists t1; -create table t1 (a int primary key, b int not null); +create table t1 (a int not null default 0 primary key, b int not null default 0); insert into t1 () values (); insert into t1 values (1,1),(2,1),(3,1); update t1 set a=4 where b=1 limit 1; diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 9f05703e69e..806e2b6f254 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -88,7 +88,7 @@ b ifnull(t2.b,"this is null") NULL this is null NULL this is null drop table t1; -CREATE TABLE t1 (a varchar(16) NOT NULL, b smallint(6) NOT NULL, c datetime NOT NULL, d smallint(6) NOT NULL); +CREATE TABLE t1 (a varchar(16) NOT NULL default '', b smallint(6) NOT NULL default '', c datetime NOT NULL default '0000-00-00 00:00:00', d smallint(6) NOT NULL default 0); INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55"; Warnings: Warning 1265 Data truncated for column 'd' at row 1 diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 6744ffa889f..0a5efed7a25 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -257,7 +257,7 @@ favo_tijdschrift varchar(50) NOT NULL default '', favo_tv varchar(50) NOT NULL default '', favo_eten varchar(50) NOT NULL default '', favo_muziek varchar(30) NOT NULL default '', -info text NOT NULL, +info text NOT NULL default '', ipnr varchar(30) NOT NULL default '', PRIMARY KEY (member_id) ) ENGINE=MyISAM PACK_KEYS=1; diff --git a/mysql-test/r/rpl000001.result b/mysql-test/r/rpl000001.result index eef986d8f8c..434e10160a4 100644 --- a/mysql-test/r/rpl000001.result +++ b/mysql-test/r/rpl000001.result @@ -76,6 +76,10 @@ create table t1 (n int); insert into t1 values(3456); insert into mysql.user (Host, User, Password) VALUES ("10.10.10.%", "blafasel2", password("blafasel2")); +Warnings: +Warning 1364 Field 'ssl_cipher' doesn't have a default value +Warning 1364 Field 'x509_issuer' doesn't have a default value +Warning 1364 Field 'x509_subject' doesn't have a default value select select_priv,user from mysql.user where user = _binary'blafasel2'; select_priv user N blafasel2 diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 1fd519bc729..a887152705b 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -1,7 +1,7 @@ use test; drop table if exists t1; create table t1 ( -id char(16) not null, +id char(16) not null default '', data int not null ); drop table if exists t2; @@ -1725,7 +1725,7 @@ tinyint 1 -128 127 0 0 YES YES NO YES YES NO NULL,0 A very small integer tinyint unsigned 1 0 255 0 0 YES YES YES YES YES NO NULL,0 A very small integer Table Create Table t1 CREATE TABLE `t1` ( - `id` char(16) NOT NULL, + `id` char(16) NOT NULL default '', `data` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 Database Create Database @@ -1778,7 +1778,7 @@ tinyint 1 -128 127 0 0 YES YES NO YES YES NO NULL,0 A very small integer tinyint unsigned 1 0 255 0 0 YES YES YES YES YES NO NULL,0 A very small integer Table Create Table t1 CREATE TABLE `t1` ( - `id` char(16) NOT NULL, + `id` char(16) NOT NULL default '', `data` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 Database Create Database diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 45f7caa0b11..3c007f80d78 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -912,7 +912,11 @@ Warnings: Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'col1' at row 1 Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'col2' at row 1 INSERT IGNORE INTO t1 (col1) values (3); +Warnings: +Warning 1364 Field 'col2' doesn't have a default value INSERT IGNORE INTO t1 () values (); +Warnings: +Warning 1364 Field 'col2' doesn't have a default value SELECT * FROM t1; col1 col2 1 hello @@ -942,6 +946,8 @@ DROP TABLE t1; SET @@sql_mode = ''; CREATE TABLE t1 (i int not null); INSERT INTO t1 VALUES (); +Warnings: +Warning 1364 Field 'i' doesn't have a default value INSERT INTO t1 VALUES (DEFAULT); Warnings: Warning 1364 Field 'i' doesn't have a default value @@ -949,6 +955,8 @@ INSERT INTO t1 VALUES (DEFAULT(i)); ERROR HY000: Field 'i' doesn't have a default value ALTER TABLE t1 ADD j int; INSERT INTO t1 SET j = 1; +Warnings: +Warning 1364 Field 'i' doesn't have a default value INSERT INTO t1 SET j = 1, i = DEFAULT; Warnings: Warning 1364 Field 'i' doesn't have a default value diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 7b9a94ba998..a42dfd53a0a 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -502,7 +502,7 @@ select foobar, boggle from t1 where foobar = 'fish' and boggle = 10; foobar boggle fish 10 drop table t1; -create table t1 (id integer auto_increment unique,imagem LONGBLOB not null); +create table t1 (id integer auto_increment unique,imagem LONGBLOB not null default ''); insert into t1 (id) values (1); select charset(load_file('../../std_data/words.dat')), diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index 1a66f0d91d2..6433c76571d 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -21,10 +21,10 @@ time_field time, date_time datetime, blob_col blob, tinyblob_col tinyblob, -mediumblob_col mediumblob not null, -longblob_col longblob not null, -options enum('one','two','tree') not null, -flags set('one','two','tree') not null, +mediumblob_col mediumblob not null default '', +longblob_col longblob not null default '', +options enum('one','two','tree') not null , +flags set('one','two','tree') not null default '', PRIMARY KEY (auto), KEY (utiny), KEY (tiny), diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index a2e99be62ad..fba5ee02773 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -90,10 +90,12 @@ Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' a Warning 1265 Data truncated for column 'b' at row 4 insert into t2(b) values('mysqlab'); Warnings: +Warning 1364 Field 'a' doesn't have a default value Warning 1265 Data truncated for column 'b' at row 1 set sql_warnings=1; insert into t2(b) values('mysqlab'); Warnings: +Warning 1364 Field 'a' doesn't have a default value Warning 1265 Data truncated for column 'b' at row 1 set sql_warnings=0; drop table t1, t2; diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test index 1c9576c1c56..d091b38c5e8 100644 --- a/mysql-test/t/ctype_latin1_de.test +++ b/mysql-test/t/ctype_latin1_de.test @@ -66,7 +66,7 @@ drop table t1; # # The below checks both binary and character comparisons. # -create table t1 (word varchar(255) not null, word2 varchar(255) not null, index(word)); +create table t1 (word varchar(255) not null, word2 varchar(255) not null default '', index(word)); show create table t1; insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae'); update t1 set word2=word; diff --git a/mysql-test/t/ctype_many.test b/mysql-test/t/ctype_many.test index 26057e7c997..454e2c63cbb 100644 --- a/mysql-test/t/ctype_many.test +++ b/mysql-test/t/ctype_many.test @@ -8,7 +8,7 @@ SET CHARACTER SET latin1; CREATE TABLE t1 ( comment CHAR(32) ASCII NOT NULL, - koi8_ru_f CHAR(32) CHARACTER SET koi8r NOT NULL + koi8_ru_f CHAR(32) CHARACTER SET koi8r NOT NULL default '' ) CHARSET=latin5; SHOW CREATE TABLE t1; @@ -142,13 +142,13 @@ INSERT INTO t1 (koi8_ru_f,comment) VALUES (_koi8r' SET CHARACTER SET utf8; SELECT koi8_ru_f,MIN(comment),COUNT(*) FROM t1 GROUP BY 1; -ALTER TABLE t1 ADD utf8_f CHAR(32) CHARACTER SET utf8 NOT NULL; +ALTER TABLE t1 ADD utf8_f CHAR(32) CHARACTER SET utf8 NOT NULL default ''; UPDATE t1 SET utf8_f=CONVERT(koi8_ru_f USING utf8); SET CHARACTER SET koi8r; SELECT * FROM t1; -ALTER TABLE t1 ADD bin_f CHAR(32) BYTE NOT NULL; +ALTER TABLE t1 ADD bin_f CHAR(32) BYTE NOT NULL default ''; UPDATE t1 SET bin_f=koi8_ru_f; SELECT COUNT(DISTINCT bin_f),COUNT(DISTINCT koi8_ru_f),COUNT(DISTINCT utf8_f) FROM t1; diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test index 716dd38a119..da59c6ae5e4 100644 --- a/mysql-test/t/gis-rtree.test +++ b/mysql-test/t/gis-rtree.test @@ -120,7 +120,6 @@ INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText(' drop table t1; CREATE TABLE t1 ( - geoobjid INT NOT NULL, line LINESTRING NOT NULL, kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po', name VARCHAR(32), diff --git a/mysql-test/t/index_merge_ror.test b/mysql-test/t/index_merge_ror.test index 223bd241d96..5375f9d1a31 100644 --- a/mysql-test/t/index_merge_ror.test +++ b/mysql-test/t/index_merge_ror.test @@ -8,13 +8,13 @@ drop table if exists t0,t1,t2; create table t1 ( /* Field names reflect value(rowid) distribution, st=STairs, swt= SaWTooth */ - st_a int not null, - swt1a int not null, - swt2a int not null, + st_a int not null default 0, + swt1a int not null default 0, + swt2a int not null default 0, - st_b int not null, - swt1b int not null, - swt2b int not null, + st_b int not null default 0, + swt1b int not null default 0, + swt2b int not null default 0, /* fields/keys for row retrieval tests */ key1 int, diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test index 61c57c9b468..05c5c5298aa 100644 --- a/mysql-test/t/limit.test +++ b/mysql-test/t/limit.test @@ -6,7 +6,7 @@ drop table if exists t1; --enable_warnings -create table t1 (a int primary key, b int not null); +create table t1 (a int not null default 0 primary key, b int not null default 0); insert into t1 () values (); -- Testing default values insert into t1 values (1,1),(2,1),(3,1); update t1 set a=4 where b=1 limit 1; diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test index 4bc6a4f051a..934b165f604 100644 --- a/mysql-test/t/null.test +++ b/mysql-test/t/null.test @@ -59,7 +59,7 @@ drop table t1; # # Test inserting and updating with NULL # -CREATE TABLE t1 (a varchar(16) NOT NULL, b smallint(6) NOT NULL, c datetime NOT NULL, d smallint(6) NOT NULL); +CREATE TABLE t1 (a varchar(16) NOT NULL default '', b smallint(6) NOT NULL default '', c datetime NOT NULL default '0000-00-00 00:00:00', d smallint(6) NOT NULL default 0); INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55"; UPDATE t1 SET d=1/NULL; UPDATE t1 SET d=NULL; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index dd36cd95969..deb77baeb0e 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -206,7 +206,7 @@ CREATE TABLE t1 ( favo_tv varchar(50) NOT NULL default '', favo_eten varchar(50) NOT NULL default '', favo_muziek varchar(30) NOT NULL default '', - info text NOT NULL, + info text NOT NULL default '', ipnr varchar(30) NOT NULL default '', PRIMARY KEY (member_id) ) ENGINE=MyISAM PACK_KEYS=1; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 6aafbed6b97..dc512030a60 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -102,7 +102,7 @@ drop table t1; # Do a create table that tries to cover all types and options # create table t1 ( -type_bool bool not null, +type_bool bool not null default false, type_tiny tinyint not null auto_increment primary key, type_short smallint(3), type_mediumint mediumint, @@ -113,9 +113,9 @@ empty_char char(0), type_char char(2), type_varchar varchar(10), type_timestamp timestamp not null, -type_date date not null, -type_time time not null, -type_datetime datetime not null, +type_date date not null default '0000-00-00', +type_time time not null default '00:00:00', +type_datetime datetime not null default '0000-00-00 00:00:00', type_year year, type_enum enum ('red', 'green', 'blue'), type_set enum ('red', 'green', 'blue'), diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 4f556e34d51..c4dc1b36247 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -11,7 +11,7 @@ use test; drop table if exists t1; --enable_warnings create table t1 ( - id char(16) not null, + id char(16) not null default '', data int not null ); --disable_warnings diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 20a501bb5ed..a45bc3c4c47 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -301,7 +301,7 @@ drop table t1; # Bug when blob is updated # -create table t1 (id integer auto_increment unique,imagem LONGBLOB not null); +create table t1 (id integer auto_increment unique,imagem LONGBLOB not null default ''); insert into t1 (id) values (1); select charset(load_file('../../std_data/words.dat')), diff --git a/mysql-test/t/type_ranges.test b/mysql-test/t/type_ranges.test index 5f035921064..1f80c9cf458 100644 --- a/mysql-test/t/type_ranges.test +++ b/mysql-test/t/type_ranges.test @@ -28,10 +28,10 @@ CREATE TABLE t1 ( date_time datetime, blob_col blob, tinyblob_col tinyblob, - mediumblob_col mediumblob not null, - longblob_col longblob not null, - options enum('one','two','tree') not null, - flags set('one','two','tree') not null, + mediumblob_col mediumblob not null default '', + longblob_col longblob not null default '', + options enum('one','two','tree') not null , + flags set('one','two','tree') not null default '', PRIMARY KEY (auto), KEY (utiny), KEY (tiny), diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index d93010d9915..1032783d991 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -881,19 +881,20 @@ err: int check_that_all_fields_are_given_values(THD *thd, TABLE *entry) { - if (!thd->abort_on_warning) // No check if not strict mode - return 0; - + int err= 0; for (Field **field=entry->field ; *field ; field++) { if ((*field)->query_id != thd->query_id && ((*field)->flags & NO_DEFAULT_VALUE_FLAG)) { - my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), (*field)->field_name); - return 1; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_NO_DEFAULT_FOR_FIELD, + ER(ER_NO_DEFAULT_FOR_FIELD), + (*field)->field_name); + err= 1; } } - return 0; + return thd->abort_on_warning ? err : 0; } /***************************************************************************** From 624f855e948c374bda73f0594e4be9090dd90be0 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Wed, 23 Feb 2005 17:58:20 -0800 Subject: [PATCH 03/83] Make sure that warning message when GROUP_CONCAT() cuts values is also updated with the correct number of lines. (Bug #8681) --- mysql-test/r/join_outer.result | 19 +++++++++++++++++++ mysql-test/t/join_outer.test | 11 +++++++++++ sql/item_sum.cc | 23 +++++++++++++++-------- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index c045aa0d00a..1d15b2ba070 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -816,3 +816,22 @@ id text_id text_data 1 0 0-SV 2 10 10-SV DROP TABLE invoice, text_table; +set group_concat_max_len=5; +create table t1 (a int, b varchar(20)); +create table t2 (a int, c varchar(20)); +insert into t1 values (1,"aaaaaaaaaa"),(2,"bbbbbbbbbb"); +insert into t2 values (1,"cccccccccc"),(2,"dddddddddd"); +select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by t1.a; +group_concat(t1.b,t2.c) +aaaaa +bbbbb +Warnings: +Warning 1260 2 line(s) were cut by GROUP_CONCAT() +select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a; +group_concat(t1.b,t2.c) +aaaaa +bbbbb +Warnings: +Warning 1260 2 line(s) were cut by GROUP_CONCAT() +drop table t1, t2; +set group_concat_max_len=default; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index d177a68e685..62e76525d84 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -582,3 +582,14 @@ SELECT invoice.id, invoice.text_id, text_table.text_data WHERE (invoice.id LIKE '%' OR text_table.text_data LIKE '%'); DROP TABLE invoice, text_table; + +# Bug #8681: Bad warning message when group_concat() exceeds max length +set group_concat_max_len=5; +create table t1 (a int, b varchar(20)); +create table t2 (a int, c varchar(20)); +insert into t1 values (1,"aaaaaaaaaa"),(2,"bbbbbbbbbb"); +insert into t2 values (1,"cccccccccc"),(2,"dddddddddd"); +select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by t1.a; +select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a; +drop table t1, t2; +set group_concat_max_len=default; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 6bd2cc00b3e..7e9c5d09136 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1787,16 +1787,26 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, void Item_func_group_concat::cleanup() { + THD *thd= current_thd; + DBUG_ENTER("Item_func_group_concat::cleanup"); Item_sum::cleanup(); + /* Adjust warning message to include total number of cut values */ + if (warning) + { + char warn_buff[MYSQL_ERRMSG_SIZE]; + sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values); + warning->set_msg(thd, warn_buff); + warning= 0; + } + /* Free table and tree if they belong to this item (if item have not pointer to original item from which was made copy => it own its objects ) */ if (!original) { - THD *thd= current_thd; if (table) { free_tmp_table(thd, table); @@ -1809,13 +1819,6 @@ void Item_func_group_concat::cleanup() tree_mode= 0; delete_tree(tree); } - if (warning) - { - char warn_buff[MYSQL_ERRMSG_SIZE]; - sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values); - warning->set_msg(thd, warn_buff); - warning= 0; - } } DBUG_VOID_RETURN; } @@ -2076,6 +2079,10 @@ String* Item_func_group_concat::val_str(String* str) if (null_value) return 0; if (count_cut_values && !warning) + /* + ER_CUT_VALUE_GROUP_CONCAT needs an argument, but this gets set in + Item_func_group_concat::cleanup(). + */ warning= push_warning(item_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_CUT_VALUE_GROUP_CONCAT, ER(ER_CUT_VALUE_GROUP_CONCAT)); From 5eb393973f59364915a4cc9a7387f560d7453c5b Mon Sep 17 00:00:00 2001 From: "acurtis@pcgem.rdg.cyberkinetica.com" <> Date: Mon, 7 Mar 2005 13:37:10 +0000 Subject: [PATCH 04/83] Bug#6776 Failure to delete rows from mysql.func table caused by missing charset conversion for index read by pk. --- sql/sql_udf.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 0bb8ac8a28b..6566e327a9e 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -493,8 +493,11 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) tables.real_name= tables.alias= (char*) "func"; if (!(table = open_ltable(thd,&tables,TL_WRITE))) goto err; - if (!table->file->index_read_idx(table->record[0],0,(byte*) udf_name->str, - (uint) udf_name->length, + table->field[0]->store(udf_name.str, udf_name.length, system_charset_info); + table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); + if (!table->file->index_read_idx(table->record[0], 0, + (byte*) table->field[0]->ptr, + table->key_info[0].key_length HA_READ_KEY_EXACT)) { int error; From 9c86b351945af4e3cde4e48a33394a268c16429a Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Mon, 28 Mar 2005 09:59:41 -0800 Subject: [PATCH 05/83] Fix reconnect when using prepared statements, and add --disable_reconnect and --enable_reconnect to mysqltest so that it can be tested properly. (Bug #8866) --- client/mysqltest.c | 9 +++++++++ mysql-test/r/kill.result | 8 ++++++++ mysql-test/t/kill.test | 13 ++++++++----- sql-common/client.c | 27 +++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 042f84dfb9e..1c102bc1073 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -280,6 +280,7 @@ Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS, Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, Q_START_TIMER, Q_END_TIMER, Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL, +Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -365,6 +366,8 @@ const char *command_names[]= "character_set", "disable_ps_protocol", "enable_ps_protocol", + "disable_reconnect", + "enable_reconnect", 0 }; @@ -3624,6 +3627,12 @@ int main(int argc, char **argv) case Q_ENABLE_PS_PROTOCOL: ps_protocol_enabled= ps_protocol; break; + case Q_DISABLE_RECONNECT: + cur_con->mysql.reconnect= 0; + break; + case Q_ENABLE_RECONNECT: + cur_con->mysql.reconnect= 1; + break; default: processed = 0; break; } diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index 788fab8d31a..dcf17e4bf52 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -5,6 +5,14 @@ select ((@id := kill_id) - kill_id) from t1; ((@id := kill_id) - kill_id) 0 kill @id; +select 1; +ERROR HY000: MySQL server has gone away +select ((@id := kill_id) - kill_id) from t1; +((@id := kill_id) - kill_id) +0 +select @id != connection_id(); +@id != connection_id() +1 select 4; 4 4 diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index 65d4f27059f..4afb60a7bdd 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -23,12 +23,15 @@ connection con2; select ((@id := kill_id) - kill_id) from t1; kill @id; -# Wait for thread to do. ---sleep 5 -# verify that con1 is doning a reconnect connection con1; -ping -ping + +--disable_reconnect +# this statement should fail +--error 2006 +select 1; +--enable_reconnect +# this should work, and we should have a new connection_id() +select ((@id := kill_id) - kill_id) from t1; select @id != connection_id(); #make sure the server is still alive diff --git a/sql-common/client.c b/sql-common/client.c index 3de2483ef75..b1455f0976a 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2189,6 +2189,29 @@ my_bool mysql_reconnect(MYSQL *mysql) DBUG_RETURN(1); } tmp_mysql.free_me= mysql->free_me; + + /* + For each stmt in mysql->stmts, move it to tmp_mysql if it is + in state MYSQL_STMT_INIT_DONE, otherwise close it. + */ + { + LIST *element= mysql->stmts; + for (; element; element= element->next) + { + MYSQL_STMT *stmt= (MYSQL_STMT *) element->data; + if (stmt->state != MYSQL_STMT_INIT_DONE) + { + stmt->mysql= 0; + } + else + { + tmp_mysql.stmts= list_add(tmp_mysql.stmts, &stmt->list); + } + /* No need to call list_delete for statement here */ + } + mysql->stmts= NULL; + } + /* Don't free options as these are now used in tmp_mysql */ bzero((char*) &mysql->options,sizeof(mysql->options)); mysql->free_me=0; @@ -2277,6 +2300,10 @@ static void mysql_close_free(MYSQL *mysql) SYNOPSYS mysql_detach_stmt_list() stmt_list pointer to mysql->stmts + + NOTE + There is similar code in mysql_reconnect(), so changes here + should also be reflected there. */ void mysql_detach_stmt_list(LIST **stmt_list __attribute__((unused))) From fb643aba56ec3bf1876a21fdb1a07166e56544d7 Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Thu, 31 Mar 2005 21:41:07 +0200 Subject: [PATCH 06/83] Fixes for bugs reported by Stefano Di Paola (stefano.dipaola@wisec.it) Originally contained in 2005/03/03 19:51:29+01:00 serg@serg.mylan; contained in MySQL 4.1.10a; re-committed for archival purposes. --- include/my_global.h | 3 ++ isam/create.c | 5 +- merge/mrg_create.c | 2 +- myisam/mi_create.c | 14 ++--- myisammrg/myrg_create.c | 2 +- mysys/mf_tempfile.c | 8 +-- sql/ha_myisam.cc | 18 ++++--- sql/mysql_priv.h | 2 +- sql/mysqld.cc | 10 +++- sql/share/english/errmsg.txt | 2 +- sql/sql_udf.cc | 99 ++++++++++++++++++++++++------------ sql/table.cc | 6 ++- 12 files changed, 112 insertions(+), 59 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 7ca3d5e1e58..23cf0d54824 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -523,6 +523,9 @@ typedef SOCKET_SIZE_TYPE size_socket; #ifndef O_SHORT_LIVED #define O_SHORT_LIVED 0 #endif +#ifndef O_NOFOLLOW +#define O_NOFOLLOW 0 +#endif /* #define USE_RECORD_LOCK */ diff --git a/isam/create.c b/isam/create.c index 4c23f3edd11..204d3157d00 100644 --- a/isam/create.c +++ b/isam/create.c @@ -58,13 +58,14 @@ int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo, base_pos=512; /* Enough for N_STATE_INFO */ bzero((byte*) &share,sizeof(share)); if ((file = my_create(fn_format(buff,name,"",N_NAME_IEXT,4),0, - O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) + O_RDWR | O_EXCL | O_NOFOLLOW,MYF(MY_WME))) < 0) goto err; errpos=1; VOID(fn_format(buff,name,"",N_NAME_DEXT,2+4)); if (!(flags & HA_DONT_TOUCH_DATA)) { - if ((dfile = my_create(buff,0,O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) + if ((dfile = my_create(buff,0,O_RDWR | O_EXCL | O_NOFOLLOW, + MYF(MY_WME))) < 0) goto err; errpos=2; } diff --git a/merge/mrg_create.c b/merge/mrg_create.c index d55a1421647..3508b7967f4 100644 --- a/merge/mrg_create.c +++ b/merge/mrg_create.c @@ -33,7 +33,7 @@ int mrg_create(const char *name, const char**table_names) errpos=0; if ((file = my_create(fn_format(buff,name,"",MRG_NAME_EXT,4),0, - O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) + O_RDWR | O_EXCL | O_NOFOLLOW,MYF(MY_WME))) < 0) goto err; errpos=1; if (table_names) diff --git a/myisam/mi_create.c b/myisam/mi_create.c index f99a2c655d2..2cadc86f452 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -39,7 +39,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { register uint i,j; File dfile,file; - int errpos,save_errno; + int errpos,save_errno, create_mode= O_RDWR | O_TRUNC; myf create_flag; uint fields,length,max_key_length,packed,pointer,real_length_diff, key_length,info_length,key_segs,options,min_key_length_skip, @@ -176,7 +176,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, min_pack_length+=varchar_length+2*varchar_count; } if (flags & HA_CREATE_TMP_TABLE) + { options|= HA_OPTION_TMP_TABLE; + create_mode|= O_EXCL | O_NOFOLLOW; + } if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM)) { options|= HA_OPTION_CHECKSUM; @@ -533,9 +536,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, create_flag=MY_DELETE_OLD; } - if ((file= my_create_with_symlink(linkname_ptr, - filename, - 0, O_RDWR | O_TRUNC, + if ((file= my_create_with_symlink(linkname_ptr, filename, 0, create_mode, MYF(MY_WME | create_flag))) < 0) goto err; errpos=1; @@ -546,7 +547,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, if (share.base.raid_type) { (void) fn_format(filename,name,"",MI_NAME_DEXT,2+4); - if ((dfile=my_raid_create(filename,0,O_RDWR | O_TRUNC, + if ((dfile=my_raid_create(filename, 0, create_mode share.base.raid_type, share.base.raid_chunks, share.base.raid_chunksize, @@ -570,8 +571,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, create_flag=MY_DELETE_OLD; } if ((dfile= - my_create_with_symlink(linkname_ptr, filename, - 0,O_RDWR | O_TRUNC, + my_create_with_symlink(linkname_ptr, filename, 0, create_mode, MYF(MY_WME | create_flag))) < 0) goto err; } diff --git a/myisammrg/myrg_create.c b/myisammrg/myrg_create.c index 5fc3c60ff32..7ddb7ecb3b9 100644 --- a/myisammrg/myrg_create.c +++ b/myisammrg/myrg_create.c @@ -34,7 +34,7 @@ int myrg_create(const char *name, const char **table_names, errpos=0; if ((file = my_create(fn_format(buff,name,"",MYRG_NAME_EXT,4),0, - O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) + O_RDWR | O_EXCL | O_NOFOLLOW,MYF(MY_WME))) < 0) goto err; errpos=1; if (table_names) diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c index af9ff0d6711..a15bda4da6d 100644 --- a/mysys/mf_tempfile.c +++ b/mysys/mf_tempfile.c @@ -70,7 +70,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix, { strmake(to,res,FN_REFLEN-1); (*free)(res); - file=my_create(to,0, mode, MyFlags); + file=my_create(to,0, mode | O_EXCL | O_NOFOLLOW, MyFlags); } environ=old_env; } @@ -81,7 +81,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix, { strmake(to,res,FN_REFLEN-1); (*free)(res); - file=my_create(to, 0, mode, MyFlags); + file=my_create(to, 0, mode | O_EXCL | O_NOFOLLOW, MyFlags); } #elif defined(HAVE_MKSTEMP) && !defined(__NETWARE__) { @@ -143,7 +143,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix, strmake(to,res,FN_REFLEN-1); (*free)(res); file=my_create(to,0, - (int) (O_RDWR | O_BINARY | O_TRUNC | + (int) (O_RDWR | O_BINARY | O_TRUNC | O_EXCL | O_NOFOLLOW | O_TEMPORARY | O_SHORT_LIVED), MYF(MY_WME)); @@ -186,7 +186,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix, } (void) strmov(end_pos,TMP_EXT); file=my_create(to,0, - (int) (O_RDWR | O_BINARY | O_TRUNC | + (int) (O_RDWR | O_BINARY | O_TRUNC | O_EXCL | O_NOFOLLOW | O_TEMPORARY | O_SHORT_LIVED), MYF(MY_WME)); } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index a7beae664b9..58fd67ddfa3 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1334,7 +1334,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, HA_CREATE_INFO *info) { int error; - uint i,j,recpos,minpos,fieldpos,temp_length,length; + uint i,j,recpos,minpos,fieldpos,temp_length,length, create_flags; bool found_real_auto_increment=0; enum ha_base_keytype type; char buff[FN_REFLEN]; @@ -1510,17 +1510,21 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, create_info.data_file_name= info->data_file_name; create_info.index_file_name=info->index_file_name; + if (info->options & HA_LEX_CREATE_TMP_TABLE) + create_flags|= HA_CREATE_TMP_TABLE; + if (options & HA_OPTION_PACK_RECORD) + create_flags|= HA_PACK_RECORD; + if (options & HA_OPTION_CHECKSUM) + create_flags|= HA_CREATE_CHECKSUM; + if (options & HA_OPTION_DELAY_KEY_WRITE) + create_flags|= HA_CREATE_DELAY_KEY_WRITE; + /* TODO: Check that the following fn_format is really needed */ error=mi_create(fn_format(buff,name,"","",2+4), table_arg->keys,keydef, (uint) (recinfo_pos-recinfo), recinfo, 0, (MI_UNIQUEDEF*) 0, - &create_info, - (((options & HA_OPTION_PACK_RECORD) ? HA_PACK_RECORD : 0) | - ((options & HA_OPTION_CHECKSUM) ? HA_CREATE_CHECKSUM : 0) | - ((options & HA_OPTION_DELAY_KEY_WRITE) ? - HA_CREATE_DELAY_KEY_WRITE : 0))); - + &create_info, create_flags); my_free((gptr) recinfo,MYF(0)); DBUG_RETURN(error); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6218bc49f53..36eca63ab0e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -911,7 +911,7 @@ extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; extern my_bool opt_safe_show_db, opt_local_infile; extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern my_bool opt_readonly, lower_case_file_system; -extern my_bool opt_enable_named_pipe, opt_sync_frm; +extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; extern my_bool opt_secure_auth; extern uint opt_crash_binlog_innodb; extern char *shared_memory_base_name, *mysqld_unix_port; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 53dca59bc92..6eaaed2800b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -289,6 +289,7 @@ my_bool opt_console= 0, opt_bdb, opt_innodb, opt_isam, opt_ndbcluster; const char *opt_ndbcluster_connectstring= 0; my_bool opt_ndb_shm, opt_ndb_optimized_node_selection; #endif +my_bool opt_allow_suspicious_udfs; my_bool opt_readonly, use_temp_pool, relay_log_purge; my_bool opt_sync_bdb_logs, opt_sync_frm; my_bool opt_secure_auth= 0; @@ -4101,7 +4102,7 @@ enum options_mysqld OPT_BDB_MAX_LOCK, OPT_ERROR_LOG_FILE, OPT_DEFAULT_WEEK_FORMAT, - OPT_RANGE_ALLOC_BLOCK_SIZE, + OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS, OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE, OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE, OPT_SYNC_FRM, OPT_SYNC_BINLOG, @@ -4141,6 +4142,13 @@ struct my_option my_long_options[] = #endif /* HAVE_REPLICATION */ {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS, + "Allows to use UDF's consisting of only one symbol xxx() " + "without corresponing xxx_init() or xxx_deinit(). That also means " + "that one can load any function from any library, for example exit() " + "from libc.so", + (gptr*) &opt_allow_suspicious_udfs, (gptr*) &opt_allow_suspicious_udfs, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"basedir", 'b', "Path to installation directory. All paths are usually resolved relative to this.", (gptr*) &mysql_home_ptr, (gptr*) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG, diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 8ede3f61a0b..104a055417c 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -143,7 +143,7 @@ character-set=latin1 "No paths allowed for shared library", "Function '%-.64s' already exists", "Can't open shared library '%-.64s' (errno: %d %-.64s)", -"Can't find function '%-.64s' in library'", +"Can't find function '%-.64s' in library", "Function '%-.64s' is not defined", "Host '%-.64s' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'", "Host '%-.64s' is not allowed to connect to this MySQL server", diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 0bb8ac8a28b..ae89c1eaa35 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -74,32 +74,49 @@ static HASH udf_hash; static rw_lock_t THR_LOCK_udf; -static udf_func *add_udf(LEX_STRING *name, Item_result ret, char *dl, - Item_udftype typ); +static udf_func *add_udf(char *name, Item_result ret, + char *dl, Item_udftype typ); static void del_udf(udf_func *udf); static void *find_udf_dl(const char *dl); - -static void init_syms(udf_func *tmp) +static char *init_syms(udf_func *tmp, char *nm) { - char nm[MAX_FIELD_NAME+16],*end; + char *end; + + if (!((tmp->func= dlsym(tmp->dlhandle, tmp->name)))) + return tmp->name; - tmp->func = dlsym(tmp->dlhandle, tmp->name.str); end=strmov(nm,tmp->name.str); - (void) strmov(end,"_init"); - tmp->func_init = dlsym(tmp->dlhandle, nm); - (void) strmov(end,"_deinit"); - tmp->func_deinit = dlsym(tmp->dlhandle, nm); + if (tmp->type == UDFTYPE_AGGREGATE) { - (void)strmov( end, "_clear" ); - tmp->func_clear = dlsym( tmp->dlhandle, nm ); - (void)strmov( end, "_add" ); - tmp->func_add = dlsym( tmp->dlhandle, nm ); - /* Give error if _clear and _add doesn't exists */ - if (!tmp->func_clear || ! tmp->func_add) - tmp->func= 0; + (void)strmov(end, "_reset"); + if (!((tmp->func_reset= dlsym(tmp->dlhandle, nm)))) + return nm; + (void)strmov(end, "_add"); + if (!((tmp->func_add= dlsym(tmp->dlhandle, nm)))) + return nm; } + + (void) strmov(end,"_deinit"); + tmp->func_deinit= dlsym(tmp->dlhandle, nm); + + (void) strmov(end,"_init"); + tmp->func_init= dlsym(tmp->dlhandle, nm); + + /* + to prefent loading "udf" from, e.g. libc.so + let's ensure that at least one auxiliary symbol is defined + */ + if (!tmp->func_init && !tmp->func_deinit && tmp->type != UDFTYPE_AGGREGATE) + { + if (opt_allow_suspicious_udfs) + sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), nm); + else + return nm; + } + + return 0; } extern "C" byte* get_hash_key(const byte *buff,uint *length, @@ -111,7 +128,7 @@ extern "C" byte* get_hash_key(const byte *buff,uint *length, } /* -** Read all predeclared functions from func@mysql and accept all that +** Read all predeclared functions from mysql.func and accept all that ** can be used. */ @@ -153,7 +170,7 @@ void udf_init() if (simple_open_n_lock_tables(new_thd, &tables)) { DBUG_PRINT("error",("Can't open udf table")); - sql_print_error("Can't open the mysql/func table. Please run the mysql_install_db script to create it."); + sql_print_error("Can't open the mysql.func table. Please run the mysql_install_db script to create it."); goto end; } @@ -171,10 +188,22 @@ void udf_init() if (table->fields >= 4) // New func table udftype=(Item_udftype) table->field[3]->val_int(); + /* + Ensure that the .dll doesn't have a path + This is done to ensure that only approved dll from the system + directories are used (to make this even remotely secure). + */ + if (strchr(dl_name, '/') || strlen(name) > NAME_LEN) + { + sql_print_error("Invalid row in mysql.func table for function '%.64s'", + name); + continue; + } + if (!(tmp = add_udf(&name,(Item_result) table->field[1]->val_int(), dl_name, udftype))) { - sql_print_error("Can't alloc memory for udf function: name"); + sql_print_error("Can't alloc memory for udf function: '%.64s'", name); continue; } @@ -191,13 +220,15 @@ void udf_init() new_dl=1; } tmp->dlhandle = dl; - init_syms(tmp); - if (!tmp->func) { - sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name); - del_udf(tmp); - if (new_dl) - dlclose(dl); + char buf[MAX_FIELD_NAME+16], *missing; + if ((missing= init_syms(tmp, buf))) + { + sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), missing); + del_udf(tmp); + if (new_dl) + dlclose(dl); + } } } if (error > 0) @@ -406,13 +437,15 @@ int mysql_create_function(THD *thd,udf_func *udf) new_dl=1; } udf->dlhandle=dl; - init_syms(udf); - - if (udf->func == NULL) { - net_printf(thd, ER_CANT_FIND_DL_ENTRY, udf->name); - goto err; + char buf[MAX_FIELD_NAME+16], *missing; + if ((missing= init_syms(udf, buf))) + { + net_printf(thd, ER_CANT_FIND_DL_ENTRY, missing); + goto err; + } } + udf->name.str=strdup_root(&mem,udf->name.str); udf->dl=strdup_root(&mem,udf->dl); if (!(u_d=add_udf(&udf->name,udf->returns,udf->dl,udf->type))) @@ -427,7 +460,7 @@ int mysql_create_function(THD *thd,udf_func *udf) u_d->func_clear=udf->func_clear; u_d->func_add=udf->func_add; - /* create entry in mysql/func table */ + /* create entry in mysql.func table */ bzero((char*) &tables,sizeof(tables)); tables.db= (char*) "mysql"; @@ -447,7 +480,7 @@ int mysql_create_function(THD *thd,udf_func *udf) close_thread_tables(thd); if (error) { - net_printf(thd, ER_ERROR_ON_WRITE, "func@mysql",error); + net_printf(thd, ER_ERROR_ON_WRITE, "mysql.func",error); del_udf(u_d); goto err; } diff --git a/sql/table.cc b/sql/table.cc index 064d7f1afc1..cdcd5148787 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1229,6 +1229,10 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, uint key_length; ulong length; char fill[IO_SIZE]; + int create_flags= O_RDWR | O_TRUNC; + + if (create_info->options & HA_LEX_CREATE_TMP_TABLE) + create_flags|= O_EXCL | O_NOFOLLOW; #if SIZEOF_OFF_T > 4 /* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */ @@ -1243,7 +1247,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, */ set_if_smaller(create_info->raid_chunks, 255); - if ((file=my_create(name,CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) + if ((file= my_create(name, CREATE_MODE, create_flags, MYF(MY_WME))) >= 0) { bzero((char*) fileinfo,64); fileinfo[0]=(uchar) 254; fileinfo[1]= 1; fileinfo[2]= FRM_VER+3; // Header From e286515667d3cd3028092ef5c1277dff75d2ee21 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Thu, 31 Mar 2005 11:43:39 -0800 Subject: [PATCH 07/83] Fix segmentation fault in mysqlcheck when the last table checked with --auto-repair mode returned an error (such as being a merge table). (Bug #9492) --- client/mysqlcheck.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 8764611adf4..b5a80782948 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -537,6 +537,7 @@ static void print_result() my_bool found_error=0; res = mysql_use_result(sock); + prev[0] = '\0'; for (i = 0; (row = mysql_fetch_row(res)); i++) { @@ -565,7 +566,7 @@ static void print_result() putchar('\n'); } if (found_error && opt_auto_repair && what_to_do != DO_REPAIR && - (!opt_fast || strcmp(row[3],"OK"))) + !opt_fast) insert_dynamic(&tables4repair, prev); mysql_free_result(res); } From 62c83214d91b0698a6da7123a9166cff27381ede Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Thu, 31 Mar 2005 21:44:48 +0200 Subject: [PATCH 08/83] uninit variable fixed Originally contained in 2005/03/03 21:13:33+01:00 serg@serg.mylan; contained in MySQL 4.1.10a; re-committed for archival purposes. --- sql/ha_myisam.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 58fd67ddfa3..7ddb7ca25ed 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1334,7 +1334,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, HA_CREATE_INFO *info) { int error; - uint i,j,recpos,minpos,fieldpos,temp_length,length, create_flags; + uint i,j,recpos,minpos,fieldpos,temp_length,length, create_flags= 0; bool found_real_auto_increment=0; enum ha_base_keytype type; char buff[FN_REFLEN]; From 9db41fb08ee38bd3412a8ce2776d074b5b7c40e5 Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Thu, 31 Mar 2005 21:47:18 +0200 Subject: [PATCH 09/83] typos fixed Originally contained in 2005/03/03 23:10:23+01:00 serg@serg.mylan; contained in MySQL 4.1.10a; re-committed for archival purposes. --- sql/mysqld.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6eaaed2800b..988482d00d2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4143,8 +4143,8 @@ struct my_option my_long_options[] = {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS, - "Allows to use UDF's consisting of only one symbol xxx() " - "without corresponing xxx_init() or xxx_deinit(). That also means " + "Allows use of UDFs consisting of only one symbol xxx() " + "without corresponding xxx_init() or xxx_deinit(). That also means " "that one can load any function from any library, for example exit() " "from libc.so", (gptr*) &opt_allow_suspicious_udfs, (gptr*) &opt_allow_suspicious_udfs, From ccd6fe786a5fc8875ffde66200921c2bc30865ee Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Thu, 31 Mar 2005 21:57:46 +0200 Subject: [PATCH 10/83] after merge fixes Originally contained in 2005/03/03 23:57:48+01:00 serg@serg.mylan; contained in MySQL 4.1.10a; re-committed for archival purposes. --- sql/sql_udf.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index ae89c1eaa35..d20fca86323 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -83,8 +83,8 @@ static char *init_syms(udf_func *tmp, char *nm) { char *end; - if (!((tmp->func= dlsym(tmp->dlhandle, tmp->name)))) - return tmp->name; + if (!((tmp->func= dlsym(tmp->dlhandle, tmp->name.str)))) + return tmp->name.str; end=strmov(nm,tmp->name.str); @@ -193,17 +193,17 @@ void udf_init() This is done to ensure that only approved dll from the system directories are used (to make this even remotely secure). */ - if (strchr(dl_name, '/') || strlen(name) > NAME_LEN) + if (strchr(dl_name, '/') || name.length > NAME_LEN) { sql_print_error("Invalid row in mysql.func table for function '%.64s'", - name); + name.str); continue; } if (!(tmp = add_udf(&name,(Item_result) table->field[1]->val_int(), dl_name, udftype))) { - sql_print_error("Can't alloc memory for udf function: '%.64s'", name); + sql_print_error("Can't alloc memory for udf function: '%.64s'", name.str); continue; } @@ -270,7 +270,7 @@ void udf_free() { initialized= 0; rwlock_destroy(&THR_LOCK_udf); - } + } DBUG_VOID_RETURN; } From e2a3d0da36b7f5d110ac2cbf3a6cd994c5c8f6a5 Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Thu, 31 Mar 2005 22:02:05 +0200 Subject: [PATCH 11/83] Fix for a build bug. Added a missing comma. Originally contained in 2005/03/04 09:30:22+01:00 ingo@mysql.com; contained in MySQL 4.1.10a; re-committed for archival purposes. --- myisam/mi_create.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 2cadc86f452..a513f840965 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -547,7 +547,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, if (share.base.raid_type) { (void) fn_format(filename,name,"",MI_NAME_DEXT,2+4); - if ((dfile=my_raid_create(filename, 0, create_mode + if ((dfile=my_raid_create(filename, 0, create_mode, share.base.raid_type, share.base.raid_chunks, share.base.raid_chunksize, From 7f52a616f453219f7abfc3e13bbde748863068d7 Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Fri, 1 Apr 2005 18:38:19 +0200 Subject: [PATCH 12/83] Last minor things to finish MySQL 4.1.10a: - some wordings, - RPM packaging improvements. --- configure.in | 2 +- scripts/mysql_create_system_tables.sh | 4 +--- sql/mysqld.cc | 4 ++-- sql/sql_udf.cc | 12 ++++++------ support-files/mysql.spec.sh | 10 ++++++++-- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/configure.in b/configure.in index 665029accb3..314283f6012 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 4.1.10) +AM_INIT_AUTOMAKE(mysql, 4.1.10a) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index f524b322388..83fdc0639ce 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -163,9 +163,7 @@ then INSERT INTO user (host,user) values ('localhost','');" else i_u="$i_u - INSERT INTO user VALUES ('%','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); - INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0); - INSERT INTO user VALUES ('%','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','','','',0,0,0);" + INSERT INTO user VALUES ('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);" fi fi fi diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 988482d00d2..1164506a0a7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -284,12 +284,12 @@ my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol; my_bool opt_safe_user_create = 0, opt_no_mix_types = 0; my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0; my_bool opt_log_slave_updates= 0; +my_bool opt_allow_suspicious_udfs; my_bool opt_console= 0, opt_bdb, opt_innodb, opt_isam, opt_ndbcluster; #ifdef HAVE_NDBCLUSTER_DB const char *opt_ndbcluster_connectstring= 0; my_bool opt_ndb_shm, opt_ndb_optimized_node_selection; #endif -my_bool opt_allow_suspicious_udfs; my_bool opt_readonly, use_temp_pool, relay_log_purge; my_bool opt_sync_bdb_logs, opt_sync_frm; my_bool opt_secure_auth= 0; @@ -4143,7 +4143,7 @@ struct my_option my_long_options[] = {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS, - "Allows use of UDFs consisting of only one symbol xxx() " + "Allows to use UDFs consisting of only one symbol xxx() " "without corresponding xxx_init() or xxx_deinit(). That also means " "that one can load any function from any library, for example exit() " "from libc.so", diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index d20fca86323..05df069d69a 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -74,7 +74,7 @@ static HASH udf_hash; static rw_lock_t THR_LOCK_udf; -static udf_func *add_udf(char *name, Item_result ret, +static udf_func *add_udf(LEX_STRING *name, Item_result ret, char *dl, Item_udftype typ); static void del_udf(udf_func *udf); static void *find_udf_dl(const char *dl); @@ -90,8 +90,8 @@ static char *init_syms(udf_func *tmp, char *nm) if (tmp->type == UDFTYPE_AGGREGATE) { - (void)strmov(end, "_reset"); - if (!((tmp->func_reset= dlsym(tmp->dlhandle, nm)))) + (void)strmov(end, "_clear"); + if (!((tmp->func_clear= dlsym(tmp->dlhandle, nm)))) return nm; (void)strmov(end, "_add"); if (!((tmp->func_add= dlsym(tmp->dlhandle, nm)))) @@ -200,8 +200,9 @@ void udf_init() continue; } - if (!(tmp = add_udf(&name,(Item_result) table->field[1]->val_int(), - dl_name, udftype))) + + if (!(tmp= add_udf(&name,(Item_result) table->field[1]->val_int(), + dl_name, udftype))) { sql_print_error("Can't alloc memory for udf function: '%.64s'", name.str); continue; @@ -445,7 +446,6 @@ int mysql_create_function(THD *thd,udf_func *udf) goto err; } } - udf->name.str=strdup_root(&mem,udf->name.str); udf->dl=strdup_root(&mem,udf->dl); if (!(u_d=add_udf(&udf->name,udf->returns,udf->dl,udf->type))) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index b06ba462b26..07c8e6a46fb 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -276,7 +276,6 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --includedir=%{_includedir} \ --mandir=%{_mandir} \ --enable-thread-safe-client \ - --with-comment=\"Official MySQL RPM\" \ --with-readline ; # Add this for more debugging support # --with-debug @@ -333,6 +332,7 @@ BuildMySQL "--enable-shared \ --with-csv-storage-engine \ --with-example-storage-engine \ --with-embedded-server \ + --with-comment=\"MySQL Community Edition - Max (GPL)\" \ --with-server-suffix='-Max'" # Save everything for debug @@ -379,6 +379,7 @@ BuildMySQL "--disable-shared \ --with-client-ldflags='-all-static' \ $USE_OTHER_LIBC_DIR \ %endif + --with-comment=\"MySQL Community Edition - Standard (GPL)\" \ --with-server-suffix='%{server_suffix}' \ --without-embedded-server \ --without-berkeley-db \ @@ -694,7 +695,12 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog -* Monday Feb 7 2005 Tomas Ulin +* Mon Feb 14 2005 Lenz Grimmer + +* Fixed the compilation comments and moved them into the separate build sections + for Max and Standard + +* Mon Feb 7 2005 Tomas Ulin - enabled the "Ndbcluster" storage engine for the max binary - added extra make install in ndb subdir after Max build to get ndb binaries From 9e16f121455042848dd5234b46bd9ef076798dfd Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Fri, 1 Apr 2005 16:09:20 -0800 Subject: [PATCH 13/83] Fix handling of max_allowed_packet and net_buffer_length in embedded server when a size suffix (K, M, G) is added. (Bug #9472) --- sql/mysqld.cc | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d75efbd0b00..0590333a20f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5916,16 +5916,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), sf_malloc_mem_limit = atoi(argument); #endif break; -#ifdef EMBEDDED_LIBRARY - case OPT_MAX_ALLOWED_PACKET: - max_allowed_packet= atoi(argument); - global_system_variables.max_allowed_packet= max_allowed_packet; - break; - case OPT_NET_BUFFER_LENGTH: - net_buffer_length= atoi(argument); - global_system_variables.net_buffer_length= net_buffer_length; - break; -#endif #include case 'V': print_version(); @@ -6477,6 +6467,9 @@ static void get_options(int argc,char **argv) #ifndef EMBEDDED_LIBRARY if (mysqld_chroot) set_root(mysqld_chroot); +#else + max_allowed_packet= global_system_variables.max_allowed_packet; + net_buffer_length= global_system_variables.net_buffer_length; #endif fix_paths(); From 52770e8682b19f2deccc8bb4ad79a84e5bf3631e Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 4 Apr 2005 00:50:05 +0200 Subject: [PATCH 14/83] XID SQL syntax minor cleanups XA tests --- include/m_ctype.h | 2 +- mysql-test/r/xa.result | 45 +++++++++++++ mysql-test/t/xa.test | 57 ++++++++++++++++ sql/field.cc | 4 +- sql/handler.cc | 9 +-- sql/handler.h | 23 +++++-- sql/item_sum.h | 2 +- sql/lock.cc | 17 +++-- sql/sql_class.cc | 10 +-- sql/sql_lex.h | 9 +-- sql/sql_parse.cc | 18 ++--- sql/sql_yacc.yy | 150 ++++++++++++++++++++++------------------- 12 files changed, 239 insertions(+), 107 deletions(-) create mode 100644 mysql-test/r/xa.result create mode 100644 mysql-test/t/xa.test diff --git a/include/m_ctype.h b/include/m_ctype.h index c41c7385b3d..f5a1503234c 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -186,7 +186,7 @@ typedef struct my_charset_handler_st int base, char **e, int *err); double (*strntod)(struct charset_info_st *, char *s, uint l, char **e, int *err); - longlong (*my_strtoll10)(struct charset_info_st *cs, + longlong (*strtoll10)(struct charset_info_st *cs, const char *nptr, char **endptr, int *error); ulong (*scan)(struct charset_info_st *, const char *b, const char *e, int sq); diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result new file mode 100644 index 00000000000..1dde495d6ae --- /dev/null +++ b/mysql-test/r/xa.result @@ -0,0 +1,45 @@ +drop table if exists t1, t2; +create table t1 (a int) engine=innodb; +xa start 'test1'; +insert t1 values (10); +xa end 'test1'; +xa prepare 'test1'; +xa rollback 'test1'; +select * from t1; +a +xa start 'test2'; +xa start 'test-bad'; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed in the ACTIVE state +insert t1 values (20); +xa prepare 'test2'; +ERROR XAE07: XAER_RMFAIL: The command cannot be executed in the ACTIVE state +xa end 'test2'; +xa prepare 'test2'; +xa commit 'test2'; +select * from t1; +a +20 +xa start 'testa','testb'; +insert t1 values (30); +xa end 'testa','testb'; +xa start 0x7465737462, 0x2030405060, 0xb; +insert t1 values (40); +xa end 'testb',' 0@P`',11; +xa prepare 'testb',0x2030405060,11; +xa recover; +formatID gtrid_length bqual_length data +11 5 5 testb 0@P` +xa prepare 'testa','testb'; +xa recover; +formatID gtrid_length bqual_length data +11 5 5 testb 0@P` +1 5 5 testatestb +xa commit 'testb',0x2030405060,11; +xa rollback 'testa','testb'; +xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; +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 '' at line 1 +select * from t1; +a +20 +40 +drop table t1; diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test new file mode 100644 index 00000000000..1f2fb5056ed --- /dev/null +++ b/mysql-test/t/xa.test @@ -0,0 +1,57 @@ +# +# WL#1756 +# +-- source include/have_innodb.inc +--disable_warnings +drop table if exists t1, t2; +--enable_warnings +create table t1 (a int) engine=innodb; +xa start 'test1'; +insert t1 values (10); +xa end 'test1'; +xa prepare 'test1'; +xa rollback 'test1'; +select * from t1; + +xa start 'test2'; +--error 1399 +xa start 'test-bad'; +insert t1 values (20); +--error 1399 +xa prepare 'test2'; +xa end 'test2'; +xa prepare 'test2'; +xa commit 'test2'; +select * from t1; + +xa start 'testa','testb'; +insert t1 values (30); +xa end 'testa','testb'; + +connect (con1,localhost,,,); +connection con1; + +xa start 0x7465737462, 0x2030405060, 0xb; +insert t1 values (40); +xa end 'testb',' 0@P`',11; +xa prepare 'testb',0x2030405060,11; + +xa recover; + +# uncomment the line below when binlog will be able to prepare +#disconnect con1; +connection default; + +xa prepare 'testa','testb'; + +xa recover; + +xa commit 'testb',0x2030405060,11; +xa rollback 'testa','testb'; + +--error 1064 +xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'; + +select * from t1; +drop table t1; + diff --git a/sql/field.cc b/sql/field.cc index f3666f862af..bc5868fbea3 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3230,13 +3230,13 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) long store_tmp; int error; char *end; - + tmp_scan= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES); len-= tmp_scan; from+= tmp_scan; end= (char*) from+len; - tmp= cs->cset->my_strtoll10(cs, from, &end, &error); + tmp= cs->cset->strtoll10(cs, from, &end, &error); if (error != MY_ERRNO_EDOM) { diff --git a/sql/handler.cc b/sql/handler.cc index 143e56fdc7c..fd9ec7cf423 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -750,17 +750,15 @@ int ha_autocommit_or_rollback(THD *thd, int error) DBUG_RETURN(error); } -int ha_commit_or_rollback_by_xid(LEX_STRING *ident, bool commit) +int ha_commit_or_rollback_by_xid(XID *xid, bool commit) { - XID xid; handlerton **ht= handlertons, **end_ht=ht+total_ha; int res= 1; - xid.set(ident); for ( ; ht < end_ht ; ht++) if ((*ht)->recover) res= res && - (*(commit ? (*ht)->commit_by_xid : (*ht)->rollback_by_xid))(&xid); + (*(commit ? (*ht)->commit_by_xid : (*ht)->rollback_by_xid))(xid); return res; } @@ -2366,9 +2364,8 @@ TYPELIB *ha_known_exts(void) const char **ext, *old_ext; known_extensions_id= mysys_usage_id; - found_exts.push_back((char*) ".db"); for (types= sys_table_types; types->type; types++) - { + { if (*types->value == SHOW_OPTION_YES) { handler *file= get_new_handler(0,(enum db_type) types->db_type); diff --git a/sql/handler.h b/sql/handler.h index e5b63c7f25c..3751af29194 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -213,13 +213,22 @@ struct xid_t { long bqual_length; char data[XIDDATASIZE]; // not \0-terminated ! - bool eq(LEX_STRING *l) { return eq(l->length, 0, l->str); } + bool eq(struct xid_t *xid) + { return !memcmp(this, xid, sizeof(long)*3+gtrid_length+bqual_length); } bool eq(long g, long b, const char *d) { return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); } - void set(LEX_STRING *l) { set(l->length, 0, l->str); } + void set(struct xid_t *xid) + { memcpy(this, xid, sizeof(long)*3+xid->gtrid_length+xid->bqual_length); } + void set(long f, const char *g, long gl, const char *b, long bl) + { + formatID= f; + memcpy(data, g, gtrid_length= gl); + memcpy(data+gl, b, bqual_length= bl); + } void set(ulonglong xid) { my_xid tmp; + formatID= 1; set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX); memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id)); tmp= xid; @@ -228,7 +237,7 @@ struct xid_t { } void set(long g, long b, const char *d) { - formatID=1; + formatID= 1; gtrid_length= g; bqual_length= b; memcpy(data, d, g+b); @@ -244,7 +253,7 @@ struct xid_t { my_xid get_my_xid() { return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 && - *(ulong*)(data+MYSQL_XID_PREFIX_LEN) == server_id && + !memcmp(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id)) && !memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ? quick_get_my_xid() : 0; } @@ -261,8 +270,8 @@ typedef struct xid_t XID; /* handlerton is a singleton structure - one instance per storage engine - - to provide access to storage engine functionality that works on - "global" level (unlike handler class that works on per-table basis) + to provide access to storage engine functionality that works on the + "global" level (unlike handler class that works on a per-table basis) usually handlerton instance is defined statically in ha_xxx.cc as @@ -826,7 +835,7 @@ int ha_release_temporary_latches(THD *thd); /* transactions: interface to handlerton functions */ int ha_start_consistent_snapshot(THD *thd); -int ha_commit_or_rollback_by_xid(LEX_STRING *ident, bool commit); +int ha_commit_or_rollback_by_xid(XID *xid, bool commit); int ha_commit_one_phase(THD *thd, bool all); int ha_rollback_trans(THD *thd, bool all); int ha_prepare(THD *thd); diff --git a/sql/item_sum.h b/sql/item_sum.h index d03ef94b9cd..8c8360b0726 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -734,7 +734,7 @@ public: return 0; /* Null value */ cs= res->charset(); end= (char*) res->ptr()+res->length(); - return cs->cset->my_strtoll10(cs, res->ptr(), &end, &err_not_used); + return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used); } my_decimal *val_decimal(my_decimal *dec); enum Item_result result_type () const { return STRING_RESULT; } diff --git a/sql/lock.cc b/sql/lock.cc index 266e8dc4d4d..a8ccba32d4f 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -736,6 +736,13 @@ static void print_lock_error(int error, const char *table) protect_against_global_read_lock count of threads which have set protection against global read lock. + access to them is protected with a mutex LOCK_global_read_lock + + (XXX: one should never take LOCK_open if LOCK_global_read_lock is taken, + otherwise a deadlock may occur - see mysql_rm_table. Other mutexes could + be a problem too - grep the code for global_read_lock if you want to use + any other mutex here) + How blocking of threads by global read lock is achieved: that's advisory. Any piece of code which should be blocked by global read lock must be designed like this: @@ -773,7 +780,7 @@ static void print_lock_error(int error, const char *table) table instance of thd2 thd1: COMMIT; # blocked by thd3. thd1 blocks thd2 which blocks thd3 which blocks thd1: deadlock. - + Note that we need to support that one thread does FLUSH TABLES WITH READ LOCK; and then COMMIT; (that's what innobackup does, for some good reason). @@ -818,7 +825,7 @@ bool lock_global_read_lock(THD *thd) } thd->global_read_lock= GOT_GLOBAL_READ_LOCK; global_read_lock++; - thd->exit_cond(old_message); + thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock } /* We DON'T set global_read_lock_blocks_commit now, it will be set after @@ -887,8 +894,8 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, The following is only true in case of a global read locks (which is rare) and if old_message is set */ - if (unlikely(need_exit_cond)) - thd->exit_cond(old_message); + if (unlikely(need_exit_cond)) + thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock else pthread_mutex_unlock(&LOCK_global_read_lock); DBUG_RETURN(result); @@ -938,7 +945,7 @@ bool make_global_read_lock_block_commit(THD *thd) global_read_lock_blocks_commit--; // undo what we did else thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT; - thd->exit_cond(old_message); + thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock DBUG_RETURN(error); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cf7240e4dba..04de761aece 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -342,7 +342,9 @@ void THD::change_user(void) void THD::cleanup(void) { DBUG_ENTER("THD::cleanup"); - ha_rollback(this); + /* TODO uncomment the line below when binlog will be able to prepare */ + // if (transaction.xa_state != XA_PREPARED) + ha_rollback(this); if (locked_tables) { lock=locked_tables; locked_tables=0; @@ -384,17 +386,17 @@ THD::~THD() add_to_status(&global_status_var, &status_var); /* Close connection */ -#ifndef EMBEDDED_LIBRARY +#ifndef EMBEDDED_LIBRARY if (net.vio) { vio_delete(net.vio); - net_end(&net); + net_end(&net); } #endif if (!cleanup_done) cleanup(); - ha_close_connection(this); + ha_close_connection(this); sp_cache_clear(&sp_proc_cache); sp_cache_clear(&sp_func_cache); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 2391c0b7ef9..34ed1e83c86 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -696,6 +696,7 @@ typedef struct st_lex Item *default_value, *on_update_value; LEX_STRING comment, ident; LEX_USER *grant_user; + XID *xid; gptr yacc_yyss,yacc_yyvs; THD *thd; CHARSET_INFO *charset; @@ -738,7 +739,7 @@ typedef struct st_lex enum enum_tx_isolation tx_isolation; enum enum_ha_read_modes ha_read_mode; union { - enum ha_rkey_function ha_rkey_mode; + enum ha_rkey_function ha_rkey_mode; enum xa_option_words xa_opt; }; enum enum_var_type option_type; @@ -764,15 +765,15 @@ typedef struct st_lex ALTER_INFO alter_info; /* Prepared statements SQL syntax:*/ LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */ - /* + /* Prepared statement query text or name of variable that holds the prepared statement (in PREPARE ... queries) */ - LEX_STRING prepared_stmt_code; + LEX_STRING prepared_stmt_code; /* If true, prepared_stmt_code is a name of variable that holds the query */ bool prepared_stmt_code_is_varref; /* Names of user variables holding parameters (in EXECUTE) */ - List prepared_stmt_params; + List prepared_stmt_params; /* Points to part of global table list which contains time zone tables implicitly used by the statement. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 21282e9e620..a734af4b0e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4323,7 +4323,7 @@ unsent_create_error: case SQLCOM_XA_START: if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_RESUME) { - if (! thd->transaction.xid.eq(&thd->lex->ident)) + if (! thd->transaction.xid.eq(thd->lex->xid)) { my_error(ER_XAER_NOTA, MYF(0)); break; @@ -4332,7 +4332,7 @@ unsent_create_error: send_ok(thd); break; } - if (thd->lex->ident.length > MAXGTRIDSIZE || thd->lex->xa_opt != XA_NONE) + if (thd->lex->xa_opt != XA_NONE) { // JOIN is not supported yet. TODO my_error(ER_XAER_INVAL, MYF(0)); break; @@ -4350,7 +4350,7 @@ unsent_create_error: } DBUG_ASSERT(thd->transaction.xid.is_null()); thd->transaction.xa_state=XA_ACTIVE; - thd->transaction.xid.set(&thd->lex->ident); + thd->transaction.xid.set(thd->lex->xid); thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) | OPTION_BEGIN); thd->server_status|= SERVER_STATUS_IN_TRANS; @@ -4369,7 +4369,7 @@ unsent_create_error: xa_state_names[thd->transaction.xa_state]); break; } - if (!thd->transaction.xid.eq(&thd->lex->ident)) + if (!thd->transaction.xid.eq(thd->lex->xid)) { my_error(ER_XAER_NOTA, MYF(0)); break; @@ -4384,7 +4384,7 @@ unsent_create_error: xa_state_names[thd->transaction.xa_state]); break; } - if (!thd->transaction.xid.eq(&thd->lex->ident)) + if (!thd->transaction.xid.eq(thd->lex->xid)) { my_error(ER_XAER_NOTA, MYF(0)); break; @@ -4399,9 +4399,9 @@ unsent_create_error: send_ok(thd); break; case SQLCOM_XA_COMMIT: - if (!thd->transaction.xid.eq(&thd->lex->ident)) + if (!thd->transaction.xid.eq(thd->lex->xid)) { - if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 1))) + if (!(res= !ha_commit_or_rollback_by_xid(thd->lex->xid, 1))) my_error(ER_XAER_NOTA, MYF(0)); else send_ok(thd); @@ -4434,9 +4434,9 @@ unsent_create_error: thd->transaction.xa_state=XA_NOTR; break; case SQLCOM_XA_ROLLBACK: - if (!thd->transaction.xid.eq(&thd->lex->ident)) + if (!thd->transaction.xid.eq(thd->lex->xid)) { - if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 0))) + if (!(res= !ha_commit_or_rollback_by_xid(thd->lex->xid, 0))) my_error(ER_XAER_NOTA, MYF(0)); else send_ok(thd); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4924f78dc0a..3c2577acf96 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -47,13 +47,13 @@ const LEX_STRING null_lex_str={0,0}; #define yyoverflow(A,B,C,D,E,F) {ulong val= *(F); if(my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }} -#define WARN_DEPRECATED(A,B) \ +#define WARN_DEPRECATED(A,B) \ push_warning_printf(((THD *)yythd), MYSQL_ERROR::WARN_LEVEL_WARN, \ - ER_WARN_DEPRECATED_SYNTAX, \ + ER_WARN_DEPRECATED_SYNTAX, \ ER(ER_WARN_DEPRECATED_SYNTAX), (A), (B)); -#define TEST_ASSERT(A) \ - if (!(A)) \ +#define TEST_ASSERT(A) \ + if (!(A)) \ { \ yyerror(ER(ER_SYNTAX_ERROR)); \ YYABORT; \ @@ -243,7 +243,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token DUPLICATE_SYM %token DYNAMIC_SYM %token EACH_SYM -%token EALLOCATE_SYM %token ELSEIF_SYM %token ELT_FUNC %token ENABLE_SYM @@ -702,7 +701,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); union_opt select_derived_init %type - ULONG_NUM raid_types merge_insert_types + ulong_num raid_types merge_insert_types %type ulonglong_num @@ -1039,16 +1038,16 @@ master_def: Lex->mi.password = $3.str; } | - MASTER_PORT_SYM EQ ULONG_NUM + MASTER_PORT_SYM EQ ulong_num { Lex->mi.port = $3; } | - MASTER_CONNECT_RETRY_SYM EQ ULONG_NUM + MASTER_CONNECT_RETRY_SYM EQ ulong_num { Lex->mi.connect_retry = $3; } - | MASTER_SSL_SYM EQ ULONG_NUM + | MASTER_SSL_SYM EQ ulong_num { Lex->mi.ssl= $3 ? LEX_MASTER_INFO::SSL_ENABLE : LEX_MASTER_INFO::SSL_DISABLE; @@ -1102,7 +1101,7 @@ master_file_def: { Lex->mi.relay_log_name = $3.str; } - | RELAY_LOG_POS_SYM EQ ULONG_NUM + | RELAY_LOG_POS_SYM EQ ulong_num { Lex->mi.relay_log_pos = $3; /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */ @@ -1792,7 +1791,7 @@ sp_hcond_list: ; sp_cond: - ULONG_NUM + ulong_num { /* mysql errno */ $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); $$->type= sp_cond_type_t::number; @@ -2578,18 +2577,18 @@ create_table_option: | TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=storage_engine","ENGINE=storage_engine"); Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; } | MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;} | MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;} - | AVG_ROW_LENGTH opt_equal ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;} + | AVG_ROW_LENGTH opt_equal ulong_num { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;} | PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD; } | COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; } | AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;} - | PACK_KEYS_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} + | PACK_KEYS_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} | PACK_KEYS_SYM opt_equal DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} - | CHECKSUM_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; } - | DELAY_KEY_WRITE_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; } + | CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; } + | DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; } | ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; } | RAID_TYPE opt_equal raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} - | RAID_CHUNKS opt_equal ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} - | RAID_CHUNKSIZE opt_equal ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} + | RAID_CHUNKS opt_equal ulong_num { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} + | RAID_CHUNKSIZE opt_equal ulong_num { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} | UNION_SYM opt_equal '(' table_list ')' { /* Move the union list to the merge_list */ @@ -2666,7 +2665,7 @@ row_types: raid_types: RAID_STRIPED_SYM { $$= RAID_TYPE_0; } | RAID_0_SYM { $$= RAID_TYPE_0; } - | ULONG_NUM { $$=$1;}; + | ulong_num { $$=$1;}; merge_insert_types: NO_SYM { $$= MERGE_INSERT_DISABLED; } @@ -4704,7 +4703,7 @@ simple_expr: { $$= new Item_func_yearweek($3,new Item_int((char*) "0",0,1)); } | YEARWEEK '(' expr ',' expr ')' { $$= new Item_func_yearweek($3, $5); } - | BENCHMARK_SYM '(' ULONG_NUM ',' expr ')' + | BENCHMARK_SYM '(' ulong_num ',' expr ')' { $$=new Item_func_benchmark($3,$5); Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); @@ -4989,7 +4988,7 @@ table_ref: join_table_list: derived_table_list { TEST_ASSERT($$=$1); } ; - + /* Warning - may return NULL in case of incomplete SELECT */ derived_table_list: table_ref { $$=$1; } @@ -5033,7 +5032,7 @@ join_table: $$=$6; } | table_ref RIGHT opt_outer JOIN_SYM table_ref ON expr - { + { LEX *lex= Lex; TEST_ASSERT($1 && $5); if (!($$= lex->current_select->convert_right_join())) @@ -5047,7 +5046,7 @@ join_table: sel->save_names_for_using_list($1, $5); } USING '(' using_list ')' - { + { LEX *lex= Lex; if (!($$= lex->current_select->convert_right_join())) YYABORT; @@ -5063,7 +5062,7 @@ join_table: } | table_ref NATURAL JOIN_SYM table_factor { TEST_ASSERT($1 && ($$=$4)); add_join_natural($1,$4); }; - + normal_join: JOIN_SYM {} @@ -5109,9 +5108,9 @@ table_factor: sel->master_unit()->fake_select_lex; } if ($2->init_nested_join(lex->thd)) - YYABORT; + YYABORT; $$= 0; - /* incomplete derived tables return NULL, we must be + /* incomplete derived tables return NULL, we must be nested in select_derived rule to be here. */ } | '(' get_select_lex select_derived union_opt ')' opt_table_alias @@ -5119,7 +5118,7 @@ table_factor: /* Use $2 instead of Lex->current_select as derived table will alter value of Lex->current_select. */ - if (!($3 || $6) && $2->embedding && + if (!($3 || $6) && $2->embedding && !$2->embedding->nested_join->join_list.elements) { /* we have a derived table ($3 == NULL) but no alias, @@ -5144,7 +5143,7 @@ table_factor: (List *)0))) YYABORT; - sel->add_joined_table($$); + sel->add_joined_table($$); } else if ($4 || $6) @@ -5171,7 +5170,7 @@ select_derived: LEX *lex= Lex; /* for normal joins, $3 != NULL and end_nested_join() != NULL, for derived tables, both must equal NULL */ - + if (!($$= $1->end_nested_join(lex->thd)) && $3) YYABORT; if (!$3 && $$) @@ -5215,7 +5214,7 @@ select_derived_init: SELECT_SYM { LEX *lex= Lex; - SELECT_LEX *sel= lex->current_select; + SELECT_LEX *sel= lex->current_select; TABLE_LIST *embedding; if (!sel->embedding || sel->end_nested_join(lex->thd)) { @@ -5488,21 +5487,21 @@ limit_clause: ; limit_options: - ULONG_NUM + ulong_num { SELECT_LEX *sel= Select; sel->select_limit= $1; sel->offset_limit= 0L; sel->explicit_limit= 1; } - | ULONG_NUM ',' ULONG_NUM + | ulong_num ',' ulong_num { SELECT_LEX *sel= Select; sel->select_limit= $3; sel->offset_limit= $1; sel->explicit_limit= 1; } - | ULONG_NUM OFFSET_SYM ULONG_NUM + | ulong_num OFFSET_SYM ulong_num { SELECT_LEX *sel= Select; sel->select_limit= $1; @@ -5525,11 +5524,12 @@ delete_limit_clause: sel->explicit_limit= 1; }; -ULONG_NUM: - NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } +ulong_num: + NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | HEX_NUM { int error; $$= (ulong) strtol($1.str, (char**) 0, 16); } | LONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } | FLOAT_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } ; @@ -6139,7 +6139,7 @@ show_param: | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys AND_SYM MASTER_LOG_POS_SYM EQ ulonglong_num AND_SYM MASTER_SERVER_ID_SYM EQ - ULONG_NUM + ulong_num { Lex->sql_command = SQLCOM_SHOW_NEW_MASTER; Lex->mi.log_file_name = $8.str; @@ -6688,7 +6688,7 @@ fields_or_vars: | field_or_var { Lex->field_list.push_back($1); } ; - + field_or_var: simple_ident_nospvar {$$= $1;} | '@' ident_or_text @@ -6836,9 +6836,9 @@ NUM_literal: } } ; - + /********************************************************************** -** Createing different items. +** Creating different items. **********************************************************************/ insert_ident: @@ -6854,8 +6854,8 @@ table_wild: | ident '.' ident '.' '*' { $$ = new Item_field((YYTHD->client_capabilities & - CLIENT_NO_SCHEMA ? NullS : $1.str), - $3.str,"*"); + CLIENT_NO_SCHEMA ? NullS : $1.str), + $3.str,"*"); Lex->current_select->with_wild++; } ; @@ -6898,53 +6898,53 @@ simple_ident_nospvar: (Item*) new Item_ref(NullS,NullS,$1.str); } | simple_ident_q { $$= $1; } - ; + ; simple_ident_q: ident '.' ident { THD *thd= YYTHD; LEX *lex= thd->lex; - + /* FIXME This will work ok in simple_ident_nospvar case because we can't meet simple_ident_nospvar in trigger now. But it should be changed in future. */ if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_TRIGGER && - (!my_strcasecmp(system_charset_info, $1.str, "NEW") || + (!my_strcasecmp(system_charset_info, $1.str, "NEW") || !my_strcasecmp(system_charset_info, $1.str, "OLD"))) { Item_trigger_field *trg_fld; bool new_row= ($1.str[0]=='N' || $1.str[0]=='n'); - + if (lex->trg_chistics.event == TRG_EVENT_INSERT && !new_row) { my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT"); YYABORT; } - + if (lex->trg_chistics.event == TRG_EVENT_DELETE && new_row) { my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE"); YYABORT; } - + if (!(trg_fld= new Item_trigger_field(new_row ? Item_trigger_field::NEW_ROW: Item_trigger_field::OLD_ROW, $3.str))) YYABORT; - + /* Let us add this item to list of all Item_trigger_field objects in trigger. */ lex->trg_table_fields.link_in_list((byte *)trg_fld, (byte**)&trg_fld->next_trg_field); - + $$= (Item *)trg_fld; } else @@ -7073,7 +7073,7 @@ ident: ; ident_or_text: - ident { $$=$1;} + ident { $$=$1;} | TEXT_STRING_sys { $$=$1;} | LEX_HOSTNAME { $$=$1;}; @@ -8124,25 +8124,25 @@ grant_option_list: grant_option: GRANT OPTION { Lex->grant |= GRANT_ACL;} - | MAX_QUERIES_PER_HOUR ULONG_NUM + | MAX_QUERIES_PER_HOUR ulong_num { LEX *lex=Lex; lex->mqh.questions=$2; lex->mqh.specified_limits|= USER_RESOURCES::QUERIES_PER_HOUR; } - | MAX_UPDATES_PER_HOUR ULONG_NUM + | MAX_UPDATES_PER_HOUR ulong_num { LEX *lex=Lex; lex->mqh.updates=$2; lex->mqh.specified_limits|= USER_RESOURCES::UPDATES_PER_HOUR; } - | MAX_CONNECTIONS_PER_HOUR ULONG_NUM + | MAX_CONNECTIONS_PER_HOUR ulong_num { LEX *lex=Lex; lex->mqh.conn_per_hour= $2; lex->mqh.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR; } - | MAX_USER_CONNECTIONS_SYM ULONG_NUM + | MAX_USER_CONNECTIONS_SYM ulong_num { LEX *lex=Lex; lex->mqh.user_conn= $2; @@ -8413,38 +8413,52 @@ check_option: xa: XA_SYM begin_or_start xid opt_join_or_resume { - LEX *lex= Lex; - lex->sql_command = SQLCOM_XA_START; + Lex->sql_command = SQLCOM_XA_START; } | XA_SYM END xid opt_suspend_or_migrate { - LEX *lex= Lex; - lex->sql_command = SQLCOM_XA_END; + Lex->sql_command = SQLCOM_XA_END; } | XA_SYM PREPARE_SYM xid { - LEX *lex= Lex; - lex->sql_command = SQLCOM_XA_PREPARE; + Lex->sql_command = SQLCOM_XA_PREPARE; } | XA_SYM COMMIT_SYM xid opt_one_phase { - LEX *lex= Lex; - lex->sql_command = SQLCOM_XA_COMMIT; + Lex->sql_command = SQLCOM_XA_COMMIT; } | XA_SYM ROLLBACK_SYM xid { - LEX *lex= Lex; - lex->sql_command = SQLCOM_XA_ROLLBACK; + Lex->sql_command = SQLCOM_XA_ROLLBACK; } | XA_SYM RECOVER_SYM { - LEX *lex= Lex; - lex->sql_command = SQLCOM_XA_RECOVER; + Lex->sql_command = SQLCOM_XA_RECOVER; } ; -xid: ident_or_text { Lex->ident=$1; } - ; +xid: text_string + { + TEST_ASSERT($1->length() <= MAXGTRIDSIZE); + if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID)))) + YYABORT; + Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0); + } + | text_string ',' text_string + { + TEST_ASSERT($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE); + if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID)))) + YYABORT; + Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length()); + } + | text_string ',' text_string ',' ulong_num + { + TEST_ASSERT($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE); + if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID)))) + YYABORT; + Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length()); + } + ; begin_or_start: BEGIN_SYM {} | START_SYM {} From 41c036a60bedfbbfa07152111f310e3a3befc7ae Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Mon, 4 Apr 2005 12:26:05 +0200 Subject: [PATCH 15/83] BUG#6762 ALTER TABLE gives weird results and error message - Better error message when table definition has changed --- mysql-test/r/ndb_alter_table.result | 2 +- mysql-test/r/ndb_multi.result | 1 + mysql-test/t/ndb_alter_table.test | 2 +- mysql-test/t/ndb_multi.test | 2 ++ sql/ha_ndbcluster.cc | 30 +++++++++++++++++++++++++++-- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result index 88ac04db111..52ae0b58d56 100644 --- a/mysql-test/r/ndb_alter_table.result +++ b/mysql-test/r/ndb_alter_table.result @@ -179,7 +179,7 @@ a b c 2 two two alter table t1 drop index c; select * from t1 where b = 'two'; -ERROR 42S02: Table 'test.t1' doesn't exist +ERROR HY000: Table definition has changed, please retry transaction select * from t1 where b = 'two'; a b c 2 two two diff --git a/mysql-test/r/ndb_multi.result b/mysql-test/r/ndb_multi.result index 4a2389cd1ff..5696fda1c07 100644 --- a/mysql-test/r/ndb_multi.result +++ b/mysql-test/r/ndb_multi.result @@ -47,3 +47,4 @@ t2 t3 t4 drop table t1, t2, t3, t4; +drop table t1, t3, t4; diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test index f39edc0ee65..3ff2e735cb5 100644 --- a/mysql-test/t/ndb_alter_table.test +++ b/mysql-test/t/ndb_alter_table.test @@ -143,7 +143,7 @@ select * from t1 where b = 'two'; connection server1; alter table t1 drop index c; connection server2; ---error 1146 +--error 1105 select * from t1 where b = 'two'; select * from t1 where b = 'two'; connection server1; diff --git a/mysql-test/t/ndb_multi.test b/mysql-test/t/ndb_multi.test index 9286721b677..27ddd6508e9 100644 --- a/mysql-test/t/ndb_multi.test +++ b/mysql-test/t/ndb_multi.test @@ -40,5 +40,7 @@ show status like 'handler_discover%'; show tables; drop table t1, t2, t3, t4; +connection server2; +drop table t1, t3, t4; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 92d5e6119aa..53f432ccfd5 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -113,7 +113,6 @@ static const err_code_mapping err_map[]= { 4244, HA_ERR_TABLE_EXIST, 1 }, { 709, HA_ERR_NO_SUCH_TABLE, 1 }, - { 284, HA_ERR_NO_SUCH_TABLE, 1 }, { 266, HA_ERR_LOCK_WAIT_TIMEOUT, 1 }, { 274, HA_ERR_LOCK_WAIT_TIMEOUT, 1 }, @@ -363,7 +362,7 @@ void ha_ndbcluster::invalidateDictionaryCache() int ha_ndbcluster::ndb_err(NdbConnection *trans) { int res; - const NdbError err= trans->getNdbError(); + NdbError err= trans->getNdbError(); DBUG_ENTER("ndb_err"); ERR_PRINT(err); @@ -371,6 +370,33 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans) case NdbError::SchemaError: { invalidateDictionaryCache(); + + if (err.code==284) + { + /* + Check if the table is _really_ gone or if the table has + been alterend and thus changed table id + */ + NDBDICT *dict= get_ndb()->getDictionary(); + DBUG_PRINT("info", ("Check if table %s is really gone", m_tabname)); + if (!(dict->getTable(m_tabname))) + { + err= dict->getNdbError(); + DBUG_PRINT("info", ("Table not found, error: %d", err.code)); + if (err.code != 709) + DBUG_RETURN(1); + } + else + { + DBUG_PRINT("info", ("Table exist but must have changed")); + /* In 5.0, this should be replaced with a mapping to a mysql error */ + my_printf_error(ER_UNKNOWN_ERROR, + "Table definition has changed, "\ + "please retry transaction", + MYF(0)); + DBUG_RETURN(1); + } + } break; } default: From 2b8ff6949f5f9abe83aa308e2e942ac4c6ed6f4b Mon Sep 17 00:00:00 2001 From: "serg@sergbook.mylan" <> Date: Mon, 4 Apr 2005 17:58:21 +0200 Subject: [PATCH 16/83] delete isam/merge files --- config/ac-macros/ha_isam.m4 | 15 -- include/merge.h | 93 ------------ include/nisam.h | 212 -------------------------- mysql-test/include/have_isam.inc | 4 - mysql-test/r/have_isam.require | 2 - mysql-test/t/isam.test | 247 ------------------------------- 6 files changed, 573 deletions(-) delete mode 100644 config/ac-macros/ha_isam.m4 delete mode 100644 include/merge.h delete mode 100644 include/nisam.h delete mode 100644 mysql-test/include/have_isam.inc delete mode 100644 mysql-test/r/have_isam.require delete mode 100644 mysql-test/t/isam.test diff --git a/config/ac-macros/ha_isam.m4 b/config/ac-macros/ha_isam.m4 deleted file mode 100644 index 5e354dfa624..00000000000 --- a/config/ac-macros/ha_isam.m4 +++ /dev/null @@ -1,15 +0,0 @@ -AC_DEFUN([MYSQL_CHECK_ISAM], [ - AC_ARG_WITH([isam], [ - --with-isam Enable the ISAM table type], - [with_isam="$withval"], - [with_isam=no]) - - isam_libs= - if test X"$with_isam" = X"yes" - then - AC_DEFINE([HAVE_ISAM], [1], [Using old ISAM tables]) - isam_libs="\$(top_builddir)/isam/libnisam.a\ - \$(top_builddir)/merge/libmerge.a" - fi - AC_SUBST(isam_libs) -]) diff --git a/include/merge.h b/include/merge.h deleted file mode 100644 index 97cea5fabb1..00000000000 --- a/include/merge.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* This file should be included when using merge_isam_funktions */ -/* Author: Michael Widenius */ - -#ifndef _merge_h -#define _merge_h -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _my_base_h -#include -#endif -#ifndef _nisam_h -#include -#endif - -#define MRG_NAME_EXT ".MRG" - - /* Param to/from mrg_info */ - -typedef struct st_mrg_info /* Struct from h_info */ -{ - ulonglong records; /* Records in database */ - ulonglong deleted; /* Deleted records in database */ - ulonglong recpos; /* Pos for last used record */ - ulonglong data_file_length; - uint reclength; /* Recordlength */ - int errkey; /* With key was dupplicated on err */ - uint options; /* HA_OPTION_... used */ -} MERGE_INFO; - -typedef struct st_mrg_table_info -{ - N_INFO *table; - ulonglong file_offset; -} MRG_TABLE; - -typedef struct st_merge -{ - MRG_TABLE *open_tables,*current_table,*end_table,*last_used_table; - ulonglong records; /* records in tables */ - ulonglong del; /* Removed records */ - ulonglong data_file_length; - uint tables,options,reclength; - my_bool cache_in_use; - LIST open_list; -} MRG_INFO; - -typedef ulong mrg_off_t; - - /* Prototypes for merge-functions */ - -extern int mrg_close(MRG_INFO *file); -extern int mrg_delete(MRG_INFO *file,const byte *buff); -extern MRG_INFO *mrg_open(const char *name,int mode,int wait_if_locked); -extern int mrg_panic(enum ha_panic_function function); -extern int mrg_rfirst(MRG_INFO *file,byte *buf,int inx); -extern int mrg_rkey(MRG_INFO *file,byte *buf,int inx,const byte *key, - uint key_len, enum ha_rkey_function search_flag); -extern int mrg_rrnd(MRG_INFO *file,byte *buf, mrg_off_t pos); -extern int mrg_rsame(MRG_INFO *file,byte *record,int inx); -extern int mrg_update(MRG_INFO *file,const byte *old,const byte *new_rec); -extern int mrg_info(MRG_INFO *file,MERGE_INFO *x,int flag); -extern int mrg_lock_database(MRG_INFO *file,int lock_type); -extern int mrg_create(const char *name,const char **table_names); -extern int mrg_extra(MRG_INFO *file,enum ha_extra_function function); -extern ha_rows mrg_records_in_range(MRG_INFO *info,int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); - -extern mrg_off_t mrg_position(MRG_INFO *info); -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/nisam.h b/include/nisam.h deleted file mode 100644 index e8f29991a4e..00000000000 --- a/include/nisam.h +++ /dev/null @@ -1,212 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* This file should be included when using nisam_funktions */ -/* Author: Michael Widenius */ - -#ifndef _nisam_h -#define _nisam_h -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _my_base_h -#include -#endif - /* defines used by nisam-funktions */ - -#define N_MAXKEY 16 /* Max allowed keys */ -#define N_MAXKEY_SEG 16 /* Max segments for key */ -#define N_MAX_KEY_LENGTH 256 /* May be increased up to 500 */ -#define N_MAX_KEY_BUFF (N_MAX_KEY_LENGTH+N_MAXKEY_SEG+sizeof(double)-1) -#define N_MAX_POSSIBLE_KEY_BUFF 500+9 - -#define N_NAME_IEXT ".ISM" -#define N_NAME_DEXT ".ISD" -#define NI_POS_ERROR (~ (ulong) 0) - - - /* Param to/from nisam_info */ - -typedef struct st_n_isaminfo /* Struct from h_info */ -{ - ulong records; /* Records in database */ - ulong deleted; /* Deleted records in database */ - ulong recpos; /* Pos for last used record */ - ulong newrecpos; /* Pos if we write new record */ - ulong dupp_key_pos; /* Position to record with dupp key */ - ulong data_file_length, /* Length of data file */ - max_data_file_length, - index_file_length, - max_index_file_length, - delete_length; - uint reclength; /* Recordlength */ - uint mean_reclength; /* Mean recordlength (if packed) */ - uint keys; /* How many keys used */ - uint options; /* HA_OPTION_... used */ - int errkey, /* With key was dupplicated on err */ - sortkey; /* clustered by this key */ - File filenr; /* (uniq) filenr for datafile */ - time_t create_time; /* When table was created */ - time_t isamchk_time; - time_t update_time; - ulong *rec_per_key; /* for sql optimizing */ -} N_ISAMINFO; - - - /* Info saved on file for each info-part */ - -#ifdef __WATCOMC__ -#pragma pack(2) -#define uint uint16 /* Same format as in MSDOS */ -#endif - -#ifdef __ZTC__ -#pragma ZTC align 2 -#define uint uint16 /* Same format as in MSDOS */ -#endif - -typedef struct st_n_save_keyseg /* Key-portion */ -{ - uint8 type; /* Typ av nyckel (f|r sort) */ - uint8 flag; /* HA_DIFF_LENGTH */ - uint16 start; /* Start of key in record */ - uint16 length; /* Keylength */ -} N_SAVE_KEYSEG; - -typedef struct st_n_save_keydef /* Key definition with create & info */ -{ - uint8 flag; /* NOSAME, PACK_USED */ - uint8 keysegs; /* Number of key-segment */ - uint16 block_length; /* Length of keyblock (auto) */ - uint16 keylength; /* Tot length of keyparts (auto) */ - uint16 minlength; /* min length of (packed) key (auto) */ - uint16 maxlength; /* max length of (packed) key (auto) */ -} N_SAVE_KEYDEF; - -typedef struct st_n_save_recinfo /* Info of record */ -{ - int16 type; /* en_fieldtype */ - uint16 length; /* length of field */ -} N_SAVE_RECINFO; - - -#ifdef __ZTC__ -#pragma ZTC align -#undef uint -#endif - -#ifdef __WATCOMC__ -#pragma pack() -#undef uint -#endif - - -struct st_isam_info; /* For referense */ - -#ifndef ISAM_LIBRARY -typedef struct st_isam_info N_INFO; -#endif - -typedef struct st_n_keyseg /* Key-portion */ -{ - N_SAVE_KEYSEG base; -} N_KEYSEG; - - -typedef struct st_n_keydef /* Key definition with open & info */ -{ - N_SAVE_KEYDEF base; - N_KEYSEG seg[N_MAXKEY_SEG+1]; - int (*bin_search)(struct st_isam_info *info,struct st_n_keydef *keyinfo, - uchar *page,uchar *key, - uint key_len,uint comp_flag,uchar * *ret_pos, - uchar *buff); - uint (*get_key)(struct st_n_keydef *keyinfo,uint nod_flag,uchar * *page, - uchar *key); -} N_KEYDEF; - - -typedef struct st_decode_tree /* Decode huff-table */ -{ - uint16 *table; - uint quick_table_bits; - byte *intervalls; -} DECODE_TREE; - - -struct st_bit_buff; - -typedef struct st_n_recinfo /* Info of record */ -{ - N_SAVE_RECINFO base; -#ifndef NOT_PACKED_DATABASES - void (*unpack)(struct st_n_recinfo *rec,struct st_bit_buff *buff, - uchar *start,uchar *end); - enum en_fieldtype base_type; - uint space_length_bits,pack_type; - DECODE_TREE *huff_tree; -#endif -} N_RECINFO; - - -extern my_string nisam_log_filename; /* Name of logfile */ -extern uint nisam_block_size; -extern my_bool nisam_flush; - - /* Prototypes for nisam-functions */ - -extern int nisam_close(struct st_isam_info *file); -extern int nisam_delete(struct st_isam_info *file,const byte *buff); -extern struct st_isam_info *nisam_open(const char *name,int mode, - uint wait_if_locked); -extern int nisam_panic(enum ha_panic_function function); -extern int nisam_rfirst(struct st_isam_info *file,byte *buf,int inx); -extern int nisam_rkey(struct st_isam_info *file,byte *buf,int inx, - const byte *key, - uint key_len, enum ha_rkey_function search_flag); -extern int nisam_rlast(struct st_isam_info *file,byte *buf,int inx); -extern int nisam_rnext(struct st_isam_info *file,byte *buf,int inx); -extern int nisam_rprev(struct st_isam_info *file,byte *buf,int inx); -extern int nisam_rrnd(struct st_isam_info *file,byte *buf,ulong pos); -extern int nisam_rsame(struct st_isam_info *file,byte *record,int inx); -extern int nisam_rsame_with_pos(struct st_isam_info *file,byte *record, - int inx,ulong pos); -extern int nisam_update(struct st_isam_info *file,const byte *old, - const byte *new_record); -extern int nisam_write(struct st_isam_info *file,const byte *buff); -extern int nisam_info(struct st_isam_info *file,N_ISAMINFO *x,int flag); -extern ulong nisam_position(struct st_isam_info *info); -extern int nisam_lock_database(struct st_isam_info *file,int lock_type); -extern int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo, - N_RECINFO *recinfo,ulong records, - ulong reloc,uint flags,uint options, - ulong data_file_length); -extern int nisam_extra(struct st_isam_info *file, - enum ha_extra_function function); -extern ulong nisam_records_in_range(struct st_isam_info *info,int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); -extern int nisam_log(int activate_log); -extern int nisam_is_changed(struct st_isam_info *info); -extern uint _calc_blob_length(uint length , const byte *pos); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/mysql-test/include/have_isam.inc b/mysql-test/include/have_isam.inc deleted file mode 100644 index 830170c921f..00000000000 --- a/mysql-test/include/have_isam.inc +++ /dev/null @@ -1,4 +0,0 @@ --- require r/have_isam.require -disable_query_log; -show variables like "have_isam"; -enable_query_log; diff --git a/mysql-test/r/have_isam.require b/mysql-test/r/have_isam.require deleted file mode 100644 index 9b4142361ed..00000000000 --- a/mysql-test/r/have_isam.require +++ /dev/null @@ -1,2 +0,0 @@ -Variable_name Value -have_isam YES diff --git a/mysql-test/t/isam.test b/mysql-test/t/isam.test deleted file mode 100644 index f77d29fd20f..00000000000 --- a/mysql-test/t/isam.test +++ /dev/null @@ -1,247 +0,0 @@ --- source include/have_isam.inc - ---disable_warnings -drop table if exists t1,t2; ---enable_warnings - -# -# Test possible problem with rows that are about 65535 bytes long -# - -create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a)) engine=isam; - -let $1=100; -disable_query_log; ---disable_warnings -while ($1) -{ - eval insert into t1 (b) values(repeat(char(65+$1),65540-$1)); - dec $1; -} -enable_query_log; ---enable_warnings -delete from t1 where (a & 1); -select sum(length(b)) from t1; -drop table t1; - -# -# Test of auto_increment; The test for BDB tables is in bdb.test -# - -create table t1 (a int not null auto_increment,b int, primary key (a)) engine=isam; -insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4); -delete from t1 where a=4 or a=2; -insert into t1 values (NULL,4),(NULL,5),(6,6); -select * from t1; -delete from t1 where a=6; -#show table status like "t1"; -replace t1 values (3,1); -replace t1 values (3,3); -ALTER TABLE t1 add c int; -insert into t1 values (NULL,6,6); -select * from t1; -drop table t1; - -# -# Test of some CREATE TABLE's that should fail -# ---error 1121 -create table t1 (a int,b text, index(a)) engine=isam; ---error 1073 -create table t1 (a int,b text, index(b)) engine=isam; ---error 1075 -create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) engine=isam; ---error 1121 -create table t1 (ordid int(8), unique (ordid)) engine=isam; -drop table if exists t1; - -# -# Test of some show commands -# - -create table t1 (a int not null primary key, b int not null,c int not null, key(b,c)); -insert into t1 values (1,2,2),(2,2,3),(3,2,4),(4,2,4); -create table t2 engine=isam select * from t1; -optimize table t1; -check table t1,t2; -repair table t1,t2; -check table t2,t1; -lock tables t1 write; -check table t2,t1; -show columns from t1; -show full columns from t1; -show index from t1; -drop table t1,t2; - -# -# test of table with huge number of packed fields -# - -create table t1 (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int, i7 int, i8 -int, i9 int, i10 int, i11 int, i12 int, i13 int, i14 int, i15 int, i16 int, i17 -int, i18 int, i19 int, i20 int, i21 int, i22 int, i23 int, i24 int, i25 int, -i26 int, i27 int, i28 int, i29 int, i30 int, i31 int, i32 int, i33 int, i34 -int, i35 int, i36 int, i37 int, i38 int, i39 int, i40 int, i41 int, i42 int, -i43 int, i44 int, i45 int, i46 int, i47 int, i48 int, i49 int, i50 int, i51 -int, i52 int, i53 int, i54 int, i55 int, i56 int, i57 int, i58 int, i59 int, -i60 int, i61 int, i62 int, i63 int, i64 int, i65 int, i66 int, i67 int, i68 -int, i69 int, i70 int, i71 int, i72 int, i73 int, i74 int, i75 int, i76 int, -i77 int, i78 int, i79 int, i80 int, i81 int, i82 int, i83 int, i84 int, i85 -int, i86 int, i87 int, i88 int, i89 int, i90 int, i91 int, i92 int, i93 int, -i94 int, i95 int, i96 int, i97 int, i98 int, i99 int, i100 int, i101 int, i102 -int, i103 int, i104 int, i105 int, i106 int, i107 int, i108 int, i109 int, i110 -int, i111 int, i112 int, i113 int, i114 int, i115 int, i116 int, i117 int, i118 -int, i119 int, i120 int, i121 int, i122 int, i123 int, i124 int, i125 int, i126 -int, i127 int, i128 int, i129 int, i130 int, i131 int, i132 int, i133 int, i134 -int, i135 int, i136 int, i137 int, i138 int, i139 int, i140 int, i141 int, i142 -int, i143 int, i144 int, i145 int, i146 int, i147 int, i148 int, i149 int, i150 -int, i151 int, i152 int, i153 int, i154 int, i155 int, i156 int, i157 int, i158 -int, i159 int, i160 int, i161 int, i162 int, i163 int, i164 int, i165 int, i166 -int, i167 int, i168 int, i169 int, i170 int, i171 int, i172 int, i173 int, i174 -int, i175 int, i176 int, i177 int, i178 int, i179 int, i180 int, i181 int, i182 -int, i183 int, i184 int, i185 int, i186 int, i187 int, i188 int, i189 int, i190 -int, i191 int, i192 int, i193 int, i194 int, i195 int, i196 int, i197 int, i198 -int, i199 int, i200 int, i201 int, i202 int, i203 int, i204 int, i205 int, i206 -int, i207 int, i208 int, i209 int, i210 int, i211 int, i212 int, i213 int, i214 -int, i215 int, i216 int, i217 int, i218 int, i219 int, i220 int, i221 int, i222 -int, i223 int, i224 int, i225 int, i226 int, i227 int, i228 int, i229 int, i230 -int, i231 int, i232 int, i233 int, i234 int, i235 int, i236 int, i237 int, i238 -int, i239 int, i240 int, i241 int, i242 int, i243 int, i244 int, i245 int, i246 -int, i247 int, i248 int, i249 int, i250 int, i251 int, i252 int, i253 int, i254 -int, i255 int, i256 int, i257 int, i258 int, i259 int, i260 int, i261 int, i262 -int, i263 int, i264 int, i265 int, i266 int, i267 int, i268 int, i269 int, i270 -int, i271 int, i272 int, i273 int, i274 int, i275 int, i276 int, i277 int, i278 -int, i279 int, i280 int, i281 int, i282 int, i283 int, i284 int, i285 int, i286 -int, i287 int, i288 int, i289 int, i290 int, i291 int, i292 int, i293 int, i294 -int, i295 int, i296 int, i297 int, i298 int, i299 int, i300 int, i301 int, i302 -int, i303 int, i304 int, i305 int, i306 int, i307 int, i308 int, i309 int, i310 -int, i311 int, i312 int, i313 int, i314 int, i315 int, i316 int, i317 int, i318 -int, i319 int, i320 int, i321 int, i322 int, i323 int, i324 int, i325 int, i326 -int, i327 int, i328 int, i329 int, i330 int, i331 int, i332 int, i333 int, i334 -int, i335 int, i336 int, i337 int, i338 int, i339 int, i340 int, i341 int, i342 -int, i343 int, i344 int, i345 int, i346 int, i347 int, i348 int, i349 int, i350 -int, i351 int, i352 int, i353 int, i354 int, i355 int, i356 int, i357 int, i358 -int, i359 int, i360 int, i361 int, i362 int, i363 int, i364 int, i365 int, i366 -int, i367 int, i368 int, i369 int, i370 int, i371 int, i372 int, i373 int, i374 -int, i375 int, i376 int, i377 int, i378 int, i379 int, i380 int, i381 int, i382 -int, i383 int, i384 int, i385 int, i386 int, i387 int, i388 int, i389 int, i390 -int, i391 int, i392 int, i393 int, i394 int, i395 int, i396 int, i397 int, i398 -int, i399 int, i400 int, i401 int, i402 int, i403 int, i404 int, i405 int, i406 -int, i407 int, i408 int, i409 int, i410 int, i411 int, i412 int, i413 int, i414 -int, i415 int, i416 int, i417 int, i418 int, i419 int, i420 int, i421 int, i422 -int, i423 int, i424 int, i425 int, i426 int, i427 int, i428 int, i429 int, i430 -int, i431 int, i432 int, i433 int, i434 int, i435 int, i436 int, i437 int, i438 -int, i439 int, i440 int, i441 int, i442 int, i443 int, i444 int, i445 int, i446 -int, i447 int, i448 int, i449 int, i450 int, i451 int, i452 int, i453 int, i454 -int, i455 int, i456 int, i457 int, i458 int, i459 int, i460 int, i461 int, i462 -int, i463 int, i464 int, i465 int, i466 int, i467 int, i468 int, i469 int, i470 -int, i471 int, i472 int, i473 int, i474 int, i475 int, i476 int, i477 int, i478 -int, i479 int, i480 int, i481 int, i482 int, i483 int, i484 int, i485 int, i486 -int, i487 int, i488 int, i489 int, i490 int, i491 int, i492 int, i493 int, i494 -int, i495 int, i496 int, i497 int, i498 int, i499 int, i500 int, i501 int, i502 -int, i503 int, i504 int, i505 int, i506 int, i507 int, i508 int, i509 int, i510 -int, i511 int, i512 int, i513 int, i514 int, i515 int, i516 int, i517 int, i518 -int, i519 int, i520 int, i521 int, i522 int, i523 int, i524 int, i525 int, i526 -int, i527 int, i528 int, i529 int, i530 int, i531 int, i532 int, i533 int, i534 -int, i535 int, i536 int, i537 int, i538 int, i539 int, i540 int, i541 int, i542 -int, i543 int, i544 int, i545 int, i546 int, i547 int, i548 int, i549 int, i550 -int, i551 int, i552 int, i553 int, i554 int, i555 int, i556 int, i557 int, i558 -int, i559 int, i560 int, i561 int, i562 int, i563 int, i564 int, i565 int, i566 -int, i567 int, i568 int, i569 int, i570 int, i571 int, i572 int, i573 int, i574 -int, i575 int, i576 int, i577 int, i578 int, i579 int, i580 int, i581 int, i582 -int, i583 int, i584 int, i585 int, i586 int, i587 int, i588 int, i589 int, i590 -int, i591 int, i592 int, i593 int, i594 int, i595 int, i596 int, i597 int, i598 -int, i599 int, i600 int, i601 int, i602 int, i603 int, i604 int, i605 int, i606 -int, i607 int, i608 int, i609 int, i610 int, i611 int, i612 int, i613 int, i614 -int, i615 int, i616 int, i617 int, i618 int, i619 int, i620 int, i621 int, i622 -int, i623 int, i624 int, i625 int, i626 int, i627 int, i628 int, i629 int, i630 -int, i631 int, i632 int, i633 int, i634 int, i635 int, i636 int, i637 int, i638 -int, i639 int, i640 int, i641 int, i642 int, i643 int, i644 int, i645 int, i646 -int, i647 int, i648 int, i649 int, i650 int, i651 int, i652 int, i653 int, i654 -int, i655 int, i656 int, i657 int, i658 int, i659 int, i660 int, i661 int, i662 -int, i663 int, i664 int, i665 int, i666 int, i667 int, i668 int, i669 int, i670 -int, i671 int, i672 int, i673 int, i674 int, i675 int, i676 int, i677 int, i678 -int, i679 int, i680 int, i681 int, i682 int, i683 int, i684 int, i685 int, i686 -int, i687 int, i688 int, i689 int, i690 int, i691 int, i692 int, i693 int, i694 -int, i695 int, i696 int, i697 int, i698 int, i699 int, i700 int, i701 int, i702 -int, i703 int, i704 int, i705 int, i706 int, i707 int, i708 int, i709 int, i710 -int, i711 int, i712 int, i713 int, i714 int, i715 int, i716 int, i717 int, i718 -int, i719 int, i720 int, i721 int, i722 int, i723 int, i724 int, i725 int, i726 -int, i727 int, i728 int, i729 int, i730 int, i731 int, i732 int, i733 int, i734 -int, i735 int, i736 int, i737 int, i738 int, i739 int, i740 int, i741 int, i742 -int, i743 int, i744 int, i745 int, i746 int, i747 int, i748 int, i749 int, i750 -int, i751 int, i752 int, i753 int, i754 int, i755 int, i756 int, i757 int, i758 -int, i759 int, i760 int, i761 int, i762 int, i763 int, i764 int, i765 int, i766 -int, i767 int, i768 int, i769 int, i770 int, i771 int, i772 int, i773 int, i774 -int, i775 int, i776 int, i777 int, i778 int, i779 int, i780 int, i781 int, i782 -int, i783 int, i784 int, i785 int, i786 int, i787 int, i788 int, i789 int, i790 -int, i791 int, i792 int, i793 int, i794 int, i795 int, i796 int, i797 int, i798 -int, i799 int, i800 int, i801 int, i802 int, i803 int, i804 int, i805 int, i806 -int, i807 int, i808 int, i809 int, i810 int, i811 int, i812 int, i813 int, i814 -int, i815 int, i816 int, i817 int, i818 int, i819 int, i820 int, i821 int, i822 -int, i823 int, i824 int, i825 int, i826 int, i827 int, i828 int, i829 int, i830 -int, i831 int, i832 int, i833 int, i834 int, i835 int, i836 int, i837 int, i838 -int, i839 int, i840 int, i841 int, i842 int, i843 int, i844 int, i845 int, i846 -int, i847 int, i848 int, i849 int, i850 int, i851 int, i852 int, i853 int, i854 -int, i855 int, i856 int, i857 int, i858 int, i859 int, i860 int, i861 int, i862 -int, i863 int, i864 int, i865 int, i866 int, i867 int, i868 int, i869 int, i870 -int, i871 int, i872 int, i873 int, i874 int, i875 int, i876 int, i877 int, i878 -int, i879 int, i880 int, i881 int, i882 int, i883 int, i884 int, i885 int, i886 -int, i887 int, i888 int, i889 int, i890 int, i891 int, i892 int, i893 int, i894 -int, i895 int, i896 int, i897 int, i898 int, i899 int, i900 int, i901 int, i902 -int, i903 int, i904 int, i905 int, i906 int, i907 int, i908 int, i909 int, i910 -int, i911 int, i912 int, i913 int, i914 int, i915 int, i916 int, i917 int, i918 -int, i919 int, i920 int, i921 int, i922 int, i923 int, i924 int, i925 int, i926 -int, i927 int, i928 int, i929 int, i930 int, i931 int, i932 int, i933 int, i934 -int, i935 int, i936 int, i937 int, i938 int, i939 int, i940 int, i941 int, i942 -int, i943 int, i944 int, i945 int, i946 int, i947 int, i948 int, i949 int, i950 -int, i951 int, i952 int, i953 int, i954 int, i955 int, i956 int, i957 int, i958 -int, i959 int, i960 int, i961 int, i962 int, i963 int, i964 int, i965 int, i966 -int, i967 int, i968 int, i969 int, i970 int, i971 int, i972 int, i973 int, i974 -int, i975 int, i976 int, i977 int, i978 int, i979 int, i980 int, i981 int, i982 -int, i983 int, i984 int, i985 int, i986 int, i987 int, i988 int, i989 int, i990 -int, i991 int, i992 int, i993 int, i994 int, i995 int, i996 int, i997 int, i998 -int, i999 int, i1000 int, b blob) row_format=dynamic; -insert into t1 values (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, "Sergei"); -update t1 set b=repeat('a',256); -update t1 set i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0; -check table t1; -drop table t1; From 8e19abff0eeab7462141c25270c369e2331372ff Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Mon, 4 Apr 2005 21:38:05 +0200 Subject: [PATCH 17/83] Fix Bug #9517 Condition pushdown to storage engine does not work for update/delete --- mysql-test/r/ndb_condition_pushdown.result | 58 ++++++++++++++++++++- mysql-test/t/ndb_condition_pushdown.test | 59 ++++++++++++++++++++++ sql/records.cc | 7 +++ 3 files changed, 123 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ndb_condition_pushdown.result b/mysql-test/r/ndb_condition_pushdown.result index f9f4104b4ea..7f769154212 100644 --- a/mysql-test/r/ndb_condition_pushdown.result +++ b/mysql-test/r/ndb_condition_pushdown.result @@ -1023,6 +1023,62 @@ auto 1 3 4 +update t1 +set medium = 17 +where +string = "aaaa" and +vstring = "aaaa" and +bin = 0xAAAA and +vbin = 0xAAAA and +tiny = -1 and +short = -1 and +medium = -1 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_double < 2.0 and +real_decimal > 1.0 and real_decimal < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +/* bits = b'001' and */ +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01'; +delete from t1 +where +string = "aaaa" and +vstring = "aaaa" and +bin = 0xAAAA and +vbin = 0xAAAA and +tiny = -1 and +short = -1 and +medium = 17 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_double < 2.0 and +real_decimal > 1.0 and real_decimal < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +/* bits = b'001' and */ +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01'; +select count(*) from t1; +count(*) +3 explain select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1; id select_type table type possible_keys key key_len ref rows Extra @@ -1078,7 +1134,7 @@ pk1 attr1 attr2 attr3 attr4 pk1 attr1 attr2 attr3 attr4 explain select auto from t1 where string = "aaaa" collate latin1_general_ci order by auto; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where; Using filesort +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where; Using filesort explain select * from t2 where (attr1 < 2) = (attr2 < 2) order by pk1; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/t/ndb_condition_pushdown.test b/mysql-test/t/ndb_condition_pushdown.test index 540e018ad04..0ada161b813 100644 --- a/mysql-test/t/ndb_condition_pushdown.test +++ b/mysql-test/t/ndb_condition_pushdown.test @@ -954,6 +954,65 @@ bin not like concat(0xBB, '%') and vbin not like concat(0xBB, '%') order by auto; +# Update test +update t1 +set medium = 17 +where +string = "aaaa" and +vstring = "aaaa" and +bin = 0xAAAA and +vbin = 0xAAAA and +tiny = -1 and +short = -1 and +medium = -1 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_double < 2.0 and +real_decimal > 1.0 and real_decimal < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +/* bits = b'001' and */ +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01'; + +# Delete test +delete from t1 +where +string = "aaaa" and +vstring = "aaaa" and +bin = 0xAAAA and +vbin = 0xAAAA and +tiny = -1 and +short = -1 and +medium = 17 and +long_int = -1 and +longlong = -1 and +real_float > 1.0 and real_float < 2.0 and +real_double > 1.0 and real_double < 2.0 and +real_decimal > 1.0 and real_decimal < 2.0 and +utiny = 1 and +ushort = 1 and +umedium = 1 and +ulong = 1 and +ulonglong = 1 and +/* bits = b'001' and */ +options = 'one' and +flags = 'one' and +date_field = '1901-01-01' and +year_field = '1901' and +time_field = '01:01:01' and +date_time = '1901-01-01 01:01:01'; + +select count(*) from t1; + # Various tests explain select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1; diff --git a/sql/records.cc b/sql/records.cc index 00da1ac1adc..28a8e9a9aa5 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -128,6 +128,13 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, VOID(table->file->extra_opt(HA_EXTRA_CACHE, thd->variables.read_buff_size)); } + /* Condition pushdown to storage engine */ + if (thd->variables.engine_condition_pushdown && + select && select->cond && + select->cond->used_tables() & table->map && + !(select->quick || table->file->pushed_cond)) + table->file->cond_push(select->cond); + DBUG_VOID_RETURN; } /* init_read_record */ From d0c9b36224d1a81b83e1141f8af8ce8f464c3b8e Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Tue, 5 Apr 2005 02:42:23 +0400 Subject: [PATCH 18/83] Fix for BUG#8877: Implementation of "Early NULL-values filtering for ref access" (attempt2+post-review fixes) 1. update_ref_and_keys() accumulates info about null-rejecting predicates in in KEY_FIELD::null_rejecting, add_key_part saves these to KEYUSE. 2. create_ref_for_key copies them to TABLE_REF. 3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of appropiate JOIN_TAB members. Includes code cleanups: * add_key_field() params: s/COND/Item_func/ (as only Item_funcs are passed to it) * add_key_fields() params: JOIN_TAB *stat removed (wasn't used) --- sql/sql_select.cc | 164 ++++++++++++++++++++++++++++++++++++++++++---- sql/sql_select.h | 10 +++ 2 files changed, 162 insertions(+), 12 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 57b09fa40b4..42c13b4c0f4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1995,6 +1995,11 @@ typedef struct key_field_t { // Used when finding key fields uint level; uint optimize; bool eq_func; + /* + If true, the condition this struct represents will not be satisfied + when val IS NULL. + */ + bool null_rejecting; } KEY_FIELD; /* Values in optimize */ @@ -2011,6 +2016,12 @@ typedef struct key_field_t { // Used when finding key fields that are internally transformed to something like: SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL + + KEY_FIELD::null_rejecting is processed as follows: + result has null_rejecting=true if it is set for both ORed references. + for example: + (t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true + (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false */ static KEY_FIELD * @@ -2044,6 +2055,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, KEY_OPTIMIZE_EXISTS) | ((old->optimize | new_fields->optimize) & KEY_OPTIMIZE_REF_OR_NULL)); + old->null_rejecting= old->null_rejecting && + new_fields->null_rejecting; } } else if (old->eq_func && new_fields->eq_func && @@ -2055,6 +2068,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, KEY_OPTIMIZE_EXISTS) | ((old->optimize | new_fields->optimize) & KEY_OPTIMIZE_REF_OR_NULL)); + old->null_rejecting= old->null_rejecting && + new_fields->null_rejecting; } else if (old->eq_func && new_fields->eq_func && (old->val->is_null() || new_fields->val->is_null())) @@ -2065,6 +2080,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, /* Remember the NOT NULL value */ if (old->val->is_null()) old->val= new_fields->val; + /* The referred expression can be NULL: */ + old->null_rejecting= false; } else { @@ -2119,7 +2136,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, */ static void -add_key_field(KEY_FIELD **key_fields,uint and_level, COND *cond, +add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, Field *field,bool eq_func,Item **value, uint num_values, table_map usable_tables) { @@ -2221,12 +2238,29 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, COND *cond, (*key_fields)->val= *value; (*key_fields)->level= and_level; (*key_fields)->optimize= exists_optimize; + /* + If the condition has form "tbl.keypart = othertbl.field" and + othertbl.field can be NULL, there will be no matches if othertbl.field + has NULL value. + */ + (*key_fields)->null_rejecting= (cond->functype() == Item_func::EQ_FUNC) && + ((*value)->type() == Item::FIELD_ITEM) && + ((Item_field*)*value)->field->maybe_null(); (*key_fields)++; } - +/* + SYNOPSIS + add_key_fields() + key_fields Add KEY_FIELD entries to this array (and move the + pointer) + and_level AND-level (a value that is different for every n-way + AND operation) + cond Condition to analyze + usable_tables Value to pass to add_key_field +*/ static void -add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level, +add_key_fields(KEY_FIELD **key_fields,uint *and_level, COND *cond, table_map usable_tables) { if (cond->type() == Item_func::COND_ITEM) @@ -2238,20 +2272,20 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level, { Item *item; while ((item=li++)) - add_key_fields(stat,key_fields,and_level,item,usable_tables); + add_key_fields(key_fields,and_level,item,usable_tables); for (; org_key_fields != *key_fields ; org_key_fields++) org_key_fields->level= *and_level; } else { (*and_level)++; - add_key_fields(stat,key_fields,and_level,li++,usable_tables); + add_key_fields(key_fields,and_level,li++,usable_tables); Item *item; while ((item=li++)) { KEY_FIELD *start_key_fields= *key_fields; (*and_level)++; - add_key_fields(stat,key_fields,and_level,item,usable_tables); + add_key_fields(key_fields,and_level,item,usable_tables); *key_fields=merge_key_fields(org_key_fields,start_key_fields, *key_fields,++(*and_level)); } @@ -2363,6 +2397,7 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field) keyuse.keypart_map= (key_part_map) 1 << part; keyuse.used_tables=key_field->val->used_tables(); keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL; + keyuse.null_rejecting= key_field->null_rejecting; VOID(insert_dynamic(keyuse_array,(gptr) &keyuse)); } } @@ -2456,8 +2491,22 @@ sort_keyuse(KEYUSE *a,KEYUSE *b) /* Update keyuse array with all possible keys we can use to fetch rows - join_tab is a array in tablenr_order - stat is a reference array in 'prefered' order. + + SYNOPSIS + update_ref_and_keys() + thd + keyuse OUT Put here ordered array of KEYUSE structures + join_tab Array in tablenr_order + tables Number of tables in join + cond WHERE condition (note that the function analyzes + join_tab[i]->on_expr too) + normal_tables tables not inner w.r.t some outer join (ones for which + we can make ref access based the WHERE clause) + select_lex current SELECT + + RETURN + 0 - OK + 1 - Out of memory. */ static bool @@ -2478,7 +2527,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, return TRUE; if (cond) { - add_key_fields(join_tab,&end,&and_level,cond,normal_tables); + add_key_fields(&end,&and_level,cond,normal_tables); for (; field != end ; field++) { add_key_part(keyuse,field); @@ -2492,7 +2541,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, { if (join_tab[i].on_expr) { - add_key_fields(join_tab,&end,&and_level,join_tab[i].on_expr, + add_key_fields(&end,&and_level,join_tab[i].on_expr, join_tab[i].table->map); } } @@ -3232,6 +3281,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, } j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length); j->ref.key_err=1; + j->ref.null_rejecting= 0; keyuse=org_keyuse; store_key **ref_key= j->ref.key_copy; @@ -3256,6 +3306,8 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, uint maybe_null= test(keyinfo->key_part[i].null_bit); j->ref.items[i]=keyuse->val; // Save for cond removal + if (keyuse->null_rejecting) + j->ref.null_rejecting |= 1 << i; keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; if (!keyuse->used_tables && !(join->select_options & SELECT_DESCRIBE)) @@ -3410,12 +3462,99 @@ make_simple_join(JOIN *join,TABLE *tmp_table) } +inline void add_cond_and_fix(Item **e1, Item *e2) +{ + if (*e1) + { + Item *res; + if ((res= new Item_cond_and(*e1, e2))) + { + *e1= res; + res->quick_fix_field(); + } + } + else + *e1= e2; +} + + +/* + Add to join_tab->select_cond[i] "table.field IS NOT NULL" conditions we've + inferred from ref/eq_ref access performed. + + SYNOPSIS + add_not_null_conds() + join Join to process + + NOTES + This function is a part of "Early NULL-values filtering for ref access" + optimization. + + Example of this optimization: + For query SELECT * FROM t1,t2 WHERE t2.key=t1.field + and plan " any-access(t1), ref(t2.key=t1.field) " + add "t1.field IS NOT NULL" to t1's table condition. + Description of the optimization: + + We look through equalities choosen to perform ref/eq_ref access, + pick equalities that have form "tbl.part_of_key = othertbl.field" + (where othertbl is a non-const table and othertbl.field may be NULL) + and add them to conditions on correspoding tables (othertbl in this + example). + + This optimization doesn't affect the choices that ref, range, or join + optimizer make. This was intentional because this was added after 4.1 + was GA. + + Implementation overview + 1. update_ref_and_keys() accumulates info about null-rejecting + predicates in in KEY_FIELD::null_rejecting + 1.1 add_key_part saves these to KEYUSE. + 2. create_ref_for_key copies them to TABLE_REF. + 3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of + appropiate JOIN_TAB members. +*/ + +static void add_not_null_conds(JOIN *join) +{ + DBUG_ENTER("add_not_null_conds"); + for (uint i=join->const_tables ; i < join->tables ; i++) + { + JOIN_TAB *tab=join->join_tab+i; + if ((tab->type == JT_REF || tab->type == JT_REF_OR_NULL) && + !tab->table->maybe_null) + { + for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++) + { + if (tab->ref.null_rejecting & (1 << keypart)) + { + Item *item= tab->ref.items[keypart]; + DBUG_ASSERT(item->type() == Item::FIELD_ITEM); + Item_field *not_null_item= (Item_field*)item; + JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; + Item_func_isnotnull *null_rej; + if (!(null_rej= new Item_func_isnotnull(not_null_item))) + DBUG_VOID_RETURN; + + null_rej->quick_fix_field(); + //psergey-todo: Flatten AND's + DBUG_EXECUTE("where",print_where(null_rej, + referred_tab->table->table_name);); + add_cond_and_fix(&referred_tab->select_cond, null_rej); + } + } + } + } + DBUG_VOID_RETURN; +} + static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { DBUG_ENTER("make_join_select"); if (select) { + add_not_null_conds(join); table_map used_tables; if (join->tables > 1) cond->update_used_tables(); // Tablenr may have changed @@ -3472,13 +3611,14 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } if (tmp) { - DBUG_EXECUTE("where",print_where(tmp,tab->table->table_name);); SQL_SELECT *sel=tab->select=(SQL_SELECT*) join->thd->memdup((gptr) select, sizeof(SQL_SELECT)); if (!sel) DBUG_RETURN(1); // End of memory - tab->select_cond=sel->cond=tmp; + add_cond_and_fix(&tab->select_cond, tmp); + sel->cond= tab->select_cond; sel->head=tab->table; + DBUG_EXECUTE("where",print_where(tmp,tab->table->table_name);); if (tab->quick) { /* Use quick key read if it's a constant and it's not used diff --git a/sql/sql_select.h b/sql/sql_select.h index 4ea7e1b23e7..ab3b442ef74 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -31,6 +31,11 @@ typedef struct keyuse_t { uint key, keypart, optimize; key_part_map keypart_map; ha_rows ref_table_rows; + /* + If true, the comparison this value was created from will not be + satisfied if val has NULL 'value'. + */ + bool null_rejecting; } KEYUSE; class store_key; @@ -45,6 +50,11 @@ typedef struct st_table_ref byte *key_buff2; // key_buff+key_length store_key **key_copy; // Item **items; // val()'s for each keypart + /* + (null_rejecting & (1<table->table_name);); add_cond_and_fix(&referred_tab->select_cond, null_rej); From 9db39659242d089f948d934356f4428f84b65977 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 5 Apr 2005 11:35:03 +0300 Subject: [PATCH 20/83] dict0dict.c: Add a note that ENUM in new tables cannot reference ENUM in old tables, in FOREIGN KEY constraints --- innobase/dict/dict0dict.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 2bceb432aa6..cb48c86c541 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -3285,6 +3285,9 @@ try_find_index: "Cannot find an index in the referenced table where the\n" "referenced columns appear as the first columns, or column types\n" "in the table and the referenced table do not match for constraint.\n" +"Note that the internal storage type of ENUM and SET changed in\n" +"tables created with >= InnoDB-4.1.12, and such columns in old tables\n" +"cannot be referenced by such columns in new tables.\n" "See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" "for correct foreign key definition.\n", start_of_latest_foreign); From f57c7d8b118aed323a74906b31fc6e013de96bb5 Mon Sep 17 00:00:00 2001 From: "ramil@mysql.com" <> Date: Tue, 5 Apr 2005 13:40:34 +0500 Subject: [PATCH 21/83] Fix for bug #9571: Primary key creation causes server crash. --- mysql-test/r/type_bit.result | 3 +++ mysql-test/t/type_bit.test | 8 ++++++++ sql/unireg.cc | 5 ++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index c926ebb6878..04179a46285 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -377,3 +377,6 @@ hex(concat(a)) hex(concat(b)) 07 0FFE 01 01FF drop table t1; +create table t1(a int, b bit not null); +alter table t1 add primary key (a); +drop table t1; diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index f00fcfef7ab..5303a55fb25 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -112,3 +112,11 @@ insert into t1 values (7,(1<<12)-2), (0x01,0x01ff); select hex(a),hex(b) from t1; select hex(concat(a)),hex(concat(b)) from t1; drop table t1; + +# +# Bug #9571: problem with primary key creation +# + +create table t1(a int, b bit not null); +alter table t1 add primary key (a); +drop table t1; diff --git a/sql/unireg.cc b/sql/unireg.cc index 57e2c1029f1..929ca5c672e 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -679,15 +679,14 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type, null_count++; } bfill(buff,(null_length=(null_fields+7)/8),255); - null_pos=buff; + null_pos= buff + null_count / 8; List_iterator it(create_fields); thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values while ((field=it++)) { Field *regfield=make_field((char*) buff+field->offset,field->length, - field->flags & NOT_NULL_FLAG ? 0: - null_pos+null_count/8, + null_pos, null_count & 7, field->pack_flag, field->sql_type, From fed0ba272ad8c5f5eb5d946de1650aa58a8f9ba1 Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Tue, 5 Apr 2005 14:31:46 +0500 Subject: [PATCH 22/83] Code optimization(discussed with Monty) --- BitKeeper/etc/logging_ok | 1 + sql/sql_show.cc | 20 ++++---------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 8b880b7c9aa..9fecb756be0 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -59,6 +59,7 @@ gerberb@ou800.zenez.com gluh@eagle.intranet.mysql.r18.ru gluh@gluh.(none) gluh@gluh.mysql.r18.ru +gluh@mysql.com gordon@zero.local.lan greg@gcw.ath.cx greg@mysql.com diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 8280d865ec0..4b9c53b9b34 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2334,25 +2334,13 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, "NO" : "YES"); table->field[6]->store((const char*) pos, strlen((const char*) pos), cs); - - switch (field->type()) { - case FIELD_TYPE_TINY_BLOB: - case FIELD_TYPE_MEDIUM_BLOB: - case FIELD_TYPE_LONG_BLOB: - case FIELD_TYPE_BLOB: - case FIELD_TYPE_VAR_STRING: - case FIELD_TYPE_STRING: - if (field->has_charset()) - table->field[8]->store((longlong) field->representation_length()/ - field->charset()->mbmaxlen); - else - table->field[8]->store((longlong) field->representation_length()); + if (field->has_charset()) + { + table->field[8]->store((longlong) field->representation_length()/ + field->charset()->mbmaxlen); table->field[8]->set_notnull(); table->field[9]->store((longlong) field->representation_length()); table->field[9]->set_notnull(); - break; - default: - break; } { From 6c8c2d22b9b58619514998ddde4165dc27b4f36d Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Tue, 5 Apr 2005 15:12:15 +0500 Subject: [PATCH 23/83] Fix for bug#7214: information_schema: unauthorized user can see metadata the fix for 'columns' table only Rights check for 'routines' table is already done (see WL2131 Access control for SHOW ... PROCEDURE|FUNCTION ...) rename 'testtets' database to 'mysqltest' to keep number of DBs which created by mysql-test as small as possible --- mysql-test/r/information_schema.result | 45 +++++++++++++++----------- mysql-test/t/information_schema.test | 29 ++++++++++------- sql/sql_show.cc | 45 ++++++++++++++------------ 3 files changed, 70 insertions(+), 49 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 55a299e335f..0e75ebe9471 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -22,11 +22,11 @@ mysql test show databases where `database` = 't%'; Database -create database testtets; -create table testtets.t1(a int, b VARCHAR(30), KEY string_data (b)); +create database mysqltest; +create table mysqltest.t1(a int, b VARCHAR(30), KEY string_data (b)); create table test.t2(a int); create table t3(a int, KEY a_data (a)); -create table testtets.t4(a int); +create table mysqltest.t4(a int); create view v1 (c) as select table_name from information_schema.TABLES; select * from v1; c @@ -62,11 +62,11 @@ time_zone_name time_zone_transition time_zone_transition_type user +t1 +t4 t2 t3 v1 -t1 -t4 select c,table_name from v1 left join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; @@ -80,10 +80,10 @@ time_zone_leap_second time_zone_leap_second time_zone_name time_zone_name time_zone_transition time_zone_transition time_zone_transition_type time_zone_transition_type -t2 t2 -t3 t3 t1 t1 t4 t4 +t2 t2 +t3 t3 select c, v2.table_name from v1 right join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; @@ -97,18 +97,18 @@ time_zone_leap_second time_zone_leap_second time_zone_name time_zone_name time_zone_transition time_zone_transition time_zone_transition_type time_zone_transition_type -t2 t2 -t3 t3 t1 t1 t4 t4 +t2 t2 +t3 t3 select table_name from information_schema.TABLES -where table_schema = "testtets" and table_name like "t%"; +where table_schema = "mysqltest" and table_name like "t%"; table_name t1 t4 -select * from information_schema.STATISTICS where TABLE_SCHEMA = "testtets"; +select * from information_schema.STATISTICS where TABLE_SCHEMA = "mysqltest"; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT -NULL testtets t1 1 testtets string_data 1 b A NULL NULL NULL YES BTREE +NULL mysqltest t1 1 mysqltest string_data 1 b A NULL NULL NULL YES BTREE show keys from t3 where Key_name = "a_data"; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t3 1 a_data 1 a A NULL NULL NULL YES BTREE @@ -133,13 +133,22 @@ c varchar(64) utf8_general_ci NO select,insert,update,references select * from information_schema.COLUMNS where table_name="t1" and column_name= "a"; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT -NULL testtets t1 a 1 NULL YES int NULL NULL 11 0 NULL NULL int(11) select,insert,update,references -show columns from testtets.t1 where field like "%a%"; +NULL mysqltest t1 a 1 NULL YES int NULL NULL 11 0 NULL NULL int(11) select,insert,update,references +show columns from mysqltest.t1 where field like "%a%"; Field Type Null Key Default Extra a int(11) YES NULL +grant select (a) on mysqltest.t1 to mysqltest_2@localhost; +select table_name, column_name, privileges from information_schema.columns +where table_schema = 'mysqltest' and table_name = 't1'; +table_name column_name privileges +t1 a select +show columns from mysqltest.t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b varchar(30) YES MUL NULL drop view v1; -drop tables testtets.t4, testtets.t1, t2, t3; -drop database testtets; +drop tables mysqltest.t4, mysqltest.t1, t2, t3; +drop database mysqltest; select * from information_schema.CHARACTER_SETS where CHARACTER_SET_NAME like 'latin1%'; CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN @@ -352,8 +361,8 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRAN 'mysqltest_1'@'localhost' NULL test t1 a REFERENCES NO delete from mysql.user where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.db where user='mysqltest_1' or user='mysqltest_2'; -delete from mysql.tables_priv where user='mysqltest_1'; -delete from mysql.columns_priv where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1' or user='mysqltest_2'; +delete from mysql.columns_priv where user='mysqltest_1' or user='mysqltest_2'; flush privileges; drop table t1; create table t1 (a int null, primary key(a)); diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index e515cd8c77a..243c3ce6829 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -17,11 +17,11 @@ show databases where `database` = 't%'; # Test for information_schema.tables & # show tables -create database testtets; -create table testtets.t1(a int, b VARCHAR(30), KEY string_data (b)); +create database mysqltest; +create table mysqltest.t1(a int, b VARCHAR(30), KEY string_data (b)); create table test.t2(a int); create table t3(a int, KEY a_data (a)); -create table testtets.t4(a int); +create table mysqltest.t4(a int); create view v1 (c) as select table_name from information_schema.TABLES; select * from v1; select c,table_name from v1 @@ -33,9 +33,9 @@ right join information_schema.TABLES v2 on (v1.c=v2.table_name) where v1.c like "t%"; select table_name from information_schema.TABLES -where table_schema = "testtets" and table_name like "t%"; +where table_schema = "mysqltest" and table_name like "t%"; -select * from information_schema.STATISTICS where TABLE_SCHEMA = "testtets"; +select * from information_schema.STATISTICS where TABLE_SCHEMA = "mysqltest"; show keys from t3 where Key_name = "a_data"; show tables like 't%'; @@ -46,11 +46,19 @@ show full columns from mysql.db like "Insert%"; show full columns from v1; select * from information_schema.COLUMNS where table_name="t1" and column_name= "a"; -show columns from testtets.t1 where field like "%a%"; +show columns from mysqltest.t1 where field like "%a%"; + +grant select (a) on mysqltest.t1 to mysqltest_2@localhost; +connect (user3,localhost,mysqltest_2,,); +connection user3; +select table_name, column_name, privileges from information_schema.columns +where table_schema = 'mysqltest' and table_name = 't1'; +show columns from mysqltest.t1; +connection default; drop view v1; -drop tables testtets.t4, testtets.t1, t2, t3; -drop database testtets; +drop tables mysqltest.t4, mysqltest.t1, t2, t3; +drop database mysqltest; # Test for information_schema.CHARACTER_SETS & # SHOW CHARACTER SET @@ -107,7 +115,6 @@ mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8); select count(*) from information_schema.ROUTINES; connect (user1,localhost,mysqltest_1,,); -connect (user3,localhost,mysqltest_2,,); connection user1; select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES; --error 1305 @@ -166,8 +173,8 @@ select * from information_schema.TABLE_PRIVILEGES where grantee like '%mysqltest select * from information_schema.COLUMN_PRIVILEGES where grantee like '%mysqltest_1%'; delete from mysql.user where user='mysqltest_1' or user='mysqltest_2'; delete from mysql.db where user='mysqltest_1' or user='mysqltest_2'; -delete from mysql.tables_priv where user='mysqltest_1'; -delete from mysql.columns_priv where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1' or user='mysqltest_2'; +delete from mysql.columns_priv where user='mysqltest_1' or user='mysqltest_2'; flush privileges; drop table t1; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4b9c53b9b34..d92613bd633 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2290,8 +2290,32 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, char tmp[MAX_FIELD_WIDTH]; char tmp1[MAX_FIELD_WIDTH]; String type(tmp,sizeof(tmp), system_charset_info); + char *end= tmp; count++; restore_record(table, s->default_values); + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint col_access; + check_access(thd,SELECT_ACL | EXTRA_ACL, base_name, + &tables->grant.privilege, 0, 0); + col_access= get_column_grant(thd, &tables->grant, tables->db, + tables->table_name, + field->field_name) & COL_ACLS; + if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS && !col_access) + continue; + for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) + { + if (col_access & 1) + { + *end++=','; + end=strmov(end,grant_types.type_names[bitnr]); + } + } +#else + end=strmov(end,""); +#endif + table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs); + table->field[1]->store(base_name, strlen(base_name), cs); table->field[2]->store(file_name, strlen(file_name), cs); table->field[3]->store(field->field_name, strlen(field->field_name), @@ -2398,31 +2422,12 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":""); table->field[15]->store((const char*) pos, strlen((const char*) pos), cs); - char *end= tmp; + end= tmp; if (field->unireg_check == Field::NEXT_NUMBER) end=strmov(tmp,"auto_increment"); table->field[16]->store(tmp, (uint) (end-tmp), cs); end=tmp; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - uint col_access; - check_access(thd,SELECT_ACL | EXTRA_ACL, base_name, - &tables->grant.privilege, 0, 0); - col_access= get_column_grant(thd, &tables->grant, tables->db, - tables->table_name, - field->field_name) & COL_ACLS; - for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) - { - if (col_access & 1) - { - *end++=','; - end=strmov(end,grant_types.type_names[bitnr]); - } - } -#else - end=strmov(end,""); -#endif - table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs); table->field[18]->store(field->comment.str, field->comment.length, cs); if (schema_table_store_record(thd, table)) DBUG_RETURN(1); From 6ed11e3bb3fe3f720433965b4ebf02eddaf18258 Mon Sep 17 00:00:00 2001 From: "jani@ua141d10.elisa.omakaista.fi" <> Date: Tue, 5 Apr 2005 13:15:04 +0300 Subject: [PATCH 24/83] A fix for Netware. --- mysys/my_rename.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_rename.c b/mysys/my_rename.c index d4f99e83247..b5d813ad787 100644 --- a/mysys/my_rename.c +++ b/mysys/my_rename.c @@ -45,7 +45,7 @@ int my_rename(const char *from, const char *to, myf MyFlags) } #endif #if defined(HAVE_RENAME) -#ifdef __WIN__ +#if defined(__WIN__) || defined(__NETWARE__) /* On windows we can't rename over an existing file: Remove any conflicting files: From f22b8930c35e4bd080d42e4755d233c5bc6142a1 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Tue, 5 Apr 2005 13:01:16 +0200 Subject: [PATCH 25/83] Fix swedish error message --- sql/share/swedish/errmsg.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 4dc42389d89..ca863df7939 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -67,7 +67,7 @@ character-set=latin1 "Kolumn '%-.64s' fr inte vara NULL", "Oknd databas: '%-.64s'", "Tabellen '%-.64s' finns redan", -"Oknd tabell '%-.64s'", +"Oknd tabell '%-.180s'", "Kolumn '%-.64s' i %s r inte unik", "Servern gr nu ned", "Oknd kolumn '%-.64s' i %s", From 6c8624f6d55484f5aea54b2474ab0c5fdcf8b55b Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Tue, 5 Apr 2005 16:09:56 +0500 Subject: [PATCH 26/83] Fix for bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement restore original 'lex->query_tables' table list after processing of information schema table remove unnecessary operations --- mysql-test/r/ps.result | 18 ++++++++++++++++++ mysql-test/t/ps.test | 21 +++++++++++++++++++++ sql/sql_lex.h | 5 +++-- sql/sql_show.cc | 5 ++--- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 5b638fd58ab..94972ea8721 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -524,3 +524,21 @@ execute stmt using @a, @b, @c; a b c a b c deallocate prepare stmt; drop table t1,t2; +SET @aux= "SELECT COUNT(*) + FROM INFORMATION_SCHEMA.COLUMNS A, + INFORMATION_SCHEMA.COLUMNS B + WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA + AND A.TABLE_NAME = B.TABLE_NAME + AND A.COLUMN_NAME = B.COLUMN_NAME AND + A.TABLE_NAME = 'user'"; +prepare my_stmt from @aux; +execute my_stmt; +COUNT(*) +37 +execute my_stmt; +COUNT(*) +37 +execute my_stmt; +COUNT(*) +37 +deallocate prepare my_stmt; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 1af84119b79..271d553e221 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -540,3 +540,24 @@ deallocate prepare stmt; drop table t1,t2; + +# +# Bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement +# + +eval SET @aux= "SELECT COUNT(*) + FROM INFORMATION_SCHEMA.COLUMNS A, + INFORMATION_SCHEMA.COLUMNS B + WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA + AND A.TABLE_NAME = B.TABLE_NAME + AND A.COLUMN_NAME = B.COLUMN_NAME AND + A.TABLE_NAME = 'user'"; + +let $exec_loop_count= 3; +eval prepare my_stmt from @aux; +while ($exec_loop_count) +{ + eval execute my_stmt; + dec $exec_loop_count; +} +deallocate prepare my_stmt; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 8aba3be7607..32a62173059 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -701,8 +701,9 @@ typedef struct st_lex TABLE_LIST *query_tables; /* global list of all tables in this query */ /* last element next_global of previous list (used only for list building - during parsing and VIEW processing. This pointer is not valid in - mysql_execute_command + during parsing and VIEW processing. This pointer could be invalid during + processing of information schema tables(see get_schema_tables_result + function) */ TABLE_LIST **query_tables_last; TABLE_LIST *proc_table; /* refer to mysql.proc if it was opened by VIEW */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d92613bd633..d2cab6bf49f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3442,12 +3442,11 @@ bool get_schema_tables_result(JOIN *join) TABLE_LIST *table_list= tab->table->pos_in_table_list; if (table_list->schema_table && thd->fill_derived_tables()) { - TABLE_LIST *save_next_global= table_list->next_global; TABLE_LIST **query_tables_last= lex->query_tables_last; TABLE *old_derived_tables= thd->derived_tables; MYSQL_LOCK *sql_lock= thd->lock; lex->sql_command= SQLCOM_SHOW_FIELDS; - + DBUG_ASSERT(!*query_tables_last); if (&lex->unit != lex->current_select->master_unit()) // is subselect { table_list->table->file->extra(HA_EXTRA_RESET_STATE); @@ -3466,8 +3465,8 @@ bool get_schema_tables_result(JOIN *join) thd->lock= sql_lock; lex->sql_command= SQLCOM_SELECT; thd->derived_tables= old_derived_tables; - table_list->next_global= save_next_global; lex->query_tables_last= query_tables_last; + *query_tables_last= 0; } } thd->no_warnings_for_error= 0; From 114b421c8bd552bc92296073b27a21691c0ce6da Mon Sep 17 00:00:00 2001 From: "pekka@mysql.com" <> Date: Tue, 5 Apr 2005 13:14:03 +0200 Subject: [PATCH 27/83] ndb - csc#4847 release scan op early to save memory --- ndb/include/ndbapi/NdbConnection.hpp | 1 + ndb/include/ndbapi/NdbScanOperation.hpp | 2 +- ndb/src/ndbapi/NdbConnection.cpp | 31 +++++++++++++++++++++++++ ndb/src/ndbapi/NdbResultSet.cpp | 2 +- ndb/src/ndbapi/NdbScanOperation.cpp | 21 +++++++++++------ ndb/tools/desc.cpp | 2 +- 6 files changed, 49 insertions(+), 10 deletions(-) diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp index 3a9f18665e9..2ab6f7d6f64 100644 --- a/ndb/include/ndbapi/NdbConnection.hpp +++ b/ndb/include/ndbapi/NdbConnection.hpp @@ -542,6 +542,7 @@ private: // Release all cursor operations in connection void releaseOps(NdbOperation*); void releaseScanOperations(NdbIndexScanOperation*); + void releaseExecutedScanOperation(NdbIndexScanOperation*); // Set the transaction identity of the transaction void setTransactionId(Uint64 aTransactionId); diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index f25f9405033..f6e68dd4abe 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -93,7 +93,7 @@ protected: int nextResult(bool fetchAllowed = true, bool forceSend = false); virtual void release(); - void closeScan(bool forceSend = false); + void closeScan(bool forceSend = false, bool releaseOp = false); int close_impl(class TransporterFacade*, bool forceSend = false); // Overloaded methods from NdbCursorOperation diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index 0a1c7303771..e1f70160fb7 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -963,6 +963,37 @@ NdbConnection::releaseScanOperations(NdbIndexScanOperation* cursorOp) } }//NdbConnection::releaseScanOperations() +/***************************************************************************** +void releaseExecutedScanOperation(); + +Remark: Release scan op when hupp'ed trans closed (save memory) +******************************************************************************/ +void +NdbConnection::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp) +{ + DBUG_ENTER("NdbConnection::releaseExecutedScanOperation"); + DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp)) + + // here is one reason to make op lists doubly linked + if (m_firstExecutedScanOp == cursorOp) { + m_firstExecutedScanOp = (NdbIndexScanOperation*)cursorOp->theNext; + cursorOp->release(); + theNdb->releaseScanOperation(cursorOp); + } else if (m_firstExecutedScanOp != NULL) { + NdbIndexScanOperation* tOp = m_firstExecutedScanOp; + while (tOp->theNext != NULL) { + if (tOp->theNext == cursorOp) { + tOp->theNext = cursorOp->theNext; + cursorOp->release(); + theNdb->releaseScanOperation(cursorOp); + break; + } + tOp = (NdbIndexScanOperation*)tOp->theNext; + } + } + DBUG_VOID_RETURN; +}//NdbConnection::releaseExecutedScanOperation() + /***************************************************************************** NdbOperation* getNdbOperation(const char* aTableName); diff --git a/ndb/src/ndbapi/NdbResultSet.cpp b/ndb/src/ndbapi/NdbResultSet.cpp index d9d71464026..87b304126ba 100644 --- a/ndb/src/ndbapi/NdbResultSet.cpp +++ b/ndb/src/ndbapi/NdbResultSet.cpp @@ -69,7 +69,7 @@ int NdbResultSet::nextResult(bool fetchAllowed, bool forceSend) void NdbResultSet::close(bool forceSend) { - m_operation->closeScan(forceSend); + m_operation->closeScan(forceSend, true); } NdbOperation* diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 670a18f72a0..fc5a22cce17 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -674,7 +674,7 @@ NdbScanOperation::doSend(int ProcessorId) return 0; } -void NdbScanOperation::closeScan(bool forceSend) +void NdbScanOperation::closeScan(bool forceSend, bool releaseOp) { if(m_transConnection){ if(DEBUG_NEXT_RESULT) @@ -691,13 +691,20 @@ void NdbScanOperation::closeScan(bool forceSend) Guard guard(tp->theMutexPtr); close_impl(tp, forceSend); - } while(0); - - theNdbCon->theScanningOp = 0; - theNdb->closeTransaction(theNdbCon); - - theNdbCon = 0; + } + + NdbConnection* tCon = theNdbCon; + NdbConnection* tTransCon = m_transConnection; + theNdbCon = NULL; m_transConnection = NULL; + + if (releaseOp && tTransCon) { + NdbIndexScanOperation* tOp = (NdbIndexScanOperation*)this; + tTransCon->releaseExecutedScanOperation(tOp); + } + + tCon->theScanningOp = 0; + theNdb->closeTransaction(tCon); } void diff --git a/ndb/tools/desc.cpp b/ndb/tools/desc.cpp index 4287a771694..aac47c9042c 100644 --- a/ndb/tools/desc.cpp +++ b/ndb/tools/desc.cpp @@ -89,7 +89,7 @@ int main(int argc, char** argv){ unsigned j; for (j= 0; (int)j < pTab->getNoOfPrimaryKeys(); j++) { - const NdbDictionary::Column * col = pTab->getColumn(j); + const NdbDictionary::Column * col = pTab->getColumn(pTab->getPrimaryKey(j)); ndbout << col->getName(); if ((int)j < pTab->getNoOfPrimaryKeys()-1) ndbout << ", "; From 810b2c3d4059d0a03c1fcf48a9823db8a5dd5c6c Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 5 Apr 2005 13:17:49 +0200 Subject: [PATCH 28/83] remove the rest of isam/merge references fix a race condition in TC_LOG_BINLOG::unlog --- include/Makefile.am | 2 +- include/config-win.h | 1 - include/my_pthread.h | 17 ------------ include/my_sys.h | 11 ++++---- include/mysql_embed.h | 1 - mysql-test/r/replace.result | 4 +-- mysql-test/t/replace.test | 8 ++---- mysql-test/t/xa.test | 1 + mysys/my_sync.c | 22 +++++++++++---- sql/handler.cc | 4 --- sql/log.cc | 53 +++++++++++++++++++----------------- sql/mysql_priv.h | 9 +++---- sql/mysqld.cc | 54 ++++++++++--------------------------- sql/opt_range.cc | 3 +-- sql/set_var.cc | 12 +++------ sql/sql_base.cc | 1 - sql/sql_class.h | 9 ++++--- 17 files changed, 82 insertions(+), 130 deletions(-) diff --git a/include/Makefile.am b/include/Makefile.am index 08beb4b7236..5f426843950 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -24,7 +24,7 @@ pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \ sslopt-vars.h sslopt-case.h sql_common.h keycache.h \ mysql_time.h $(BUILT_SOURCES) noinst_HEADERS = config-win.h config-os2.h config-netware.h \ - nisam.h heap.h merge.h my_bitmap.h\ + heap.h my_bitmap.h\ myisam.h myisampack.h myisammrg.h ft_global.h\ mysys_err.h my_base.h help_start.h help_end.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ diff --git a/include/config-win.h b/include/config-win.h index 4ef5c9323e7..df0530fbef3 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -351,7 +351,6 @@ inline double ulonglong2double(ulonglong value) #define DO_NOT_REMOVE_THREAD_WRAPPERS #define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V)) #define thread_safe_decrement(V,L) InterlockedDecrement((long*) &(V)) -#define thread_safe_dec_and_test(V, L) thread_safe_decrement(V,L) /* The following is only used for statistics, so it should be good enough */ #ifdef __NT__ /* This should also work on Win98 but .. */ #define thread_safe_add(V,C,L) InterlockedExchangeAdd((long*) &(V),(C)) diff --git a/include/my_pthread.h b/include/my_pthread.h index b170753913b..670a4ccf63e 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -678,7 +678,6 @@ extern pthread_t shutdown_th, main_th, signal_th; #ifdef HAVE_ATOMIC_ADD #define thread_safe_increment(V,L) atomic_inc((atomic_t*) &V) #define thread_safe_decrement(V,L) atomic_dec((atomic_t*) &V) -#define thread_safe_dec_and_test(V, L) atomic_dec_and_test((atomic_t*) &V) #define thread_safe_add(V,C,L) atomic_add((C),(atomic_t*) &V) #define thread_safe_sub(V,C,L) atomic_sub((C),(atomic_t*) &V) #else @@ -689,22 +688,6 @@ extern pthread_t shutdown_th, main_th, signal_th; #define thread_safe_add(V,C,L) (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L))) #define thread_safe_sub(V,C,L) \ (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L))) -#ifdef __cplusplus -static inline bool thread_safe_dec_and_test(ulong &V, pthread_mutex_t *L) -{ - ulong res; - pthread_mutex_lock(L); - res=--V; - pthread_mutex_unlock(L); - return res==0; -} -#else -/* - what should we do ? define it as static ? - a regular function somewhere in mysys/ ? - for now it's only used in c++ code, so there's no need to bother -*/ -#endif #endif /* HAVE_ATOMIC_ADD */ #ifdef SAFE_STATISTICS #define statistic_increment(V,L) thread_safe_increment((V),(L)) diff --git a/include/my_sys.h b/include/my_sys.h index 523c0570de7..f63743a4c6c 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -54,11 +54,10 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_FAE 8 /* Fatal if any error */ #define MY_WME 16 /* Write message on error */ #define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */ -#define MY_RAID 64 /* Support for RAID (not the "Johnson&Johnson"-s one ;) */ -#define MY_FULL_IO 512 /* For my_read - loop intil I/O - is complete - */ -#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */ +#define MY_IGNORE_BADFD 32 /* my_sync: ignore 'bad descriptor' errors */ +#define MY_RAID 64 /* Support for RAID */ +#define MY_FULL_IO 512 /* For my_read - loop intil I/O is complete */ +#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */ #define MY_LINK_WARNING 32 /* my_redel() gives warning if links */ #define MY_COPYTIME 64 /* my_redel() copys time */ #define MY_DELETE_OLD 256 /* my_create_with_symlink() */ @@ -72,7 +71,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_FREE_ON_ERROR 128 /* my_realloc() ; Free old ptr on error */ #define MY_HOLD_ON_ERROR 256 /* my_realloc() ; Return old ptr on error */ #define MY_THREADSAFE 128 /* pread/pwrite: Don't allow interrupts */ -#define MY_DONT_OVERWRITE_FILE 1024 /* my_copy; Don't overwrite file */ +#define MY_DONT_OVERWRITE_FILE 1024 /* my_copy: Don't overwrite file */ #define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */ #define MY_GIVE_INFO 2 /* Give time info about process*/ diff --git a/include/mysql_embed.h b/include/mysql_embed.h index 603af8e83b8..311d95eda73 100644 --- a/include/mysql_embed.h +++ b/include/mysql_embed.h @@ -24,7 +24,6 @@ #undef HAVE_PSTACK /* No stacktrace */ #undef HAVE_DLOPEN /* No udf functions */ #undef HAVE_OPENSSL -#undef HAVE_ISAM #undef HAVE_SMEM /* No shared memory */ #undef HAVE_NDBCLUSTER_DB /* No NDB cluster */ diff --git a/mysql-test/r/replace.result b/mysql-test/r/replace.result index 83cde76215a..a7d59fcfa62 100644 --- a/mysql-test/r/replace.result +++ b/mysql-test/r/replace.result @@ -3,12 +3,10 @@ CREATE TABLE t1 ( gesuchnr int(11) DEFAULT '0' NOT NULL, benutzer_id int(11) DEFAULT '0' NOT NULL, PRIMARY KEY (gesuchnr,benutzer_id) -) engine=ISAM; +); replace into t1 (gesuchnr,benutzer_id) values (2,1); replace into t1 (gesuchnr,benutzer_id) values (1,1); replace into t1 (gesuchnr,benutzer_id) values (1,1); -alter table t1 engine=myisam; -replace into t1 (gesuchnr,benutzer_id) values (1,1); alter table t1 engine=heap; replace into t1 (gesuchnr,benutzer_id) values (1,1); drop table t1; diff --git a/mysql-test/t/replace.test b/mysql-test/t/replace.test index 8429d80a4ef..2b3775f4f67 100644 --- a/mysql-test/t/replace.test +++ b/mysql-test/t/replace.test @@ -1,7 +1,5 @@ --- source include/have_isam.inc - # -# Test of REPLACE with ISAM and MyISAM and HEAP +# Test of REPLACE with MyISAM and HEAP # --disable_warnings @@ -12,13 +10,11 @@ CREATE TABLE t1 ( gesuchnr int(11) DEFAULT '0' NOT NULL, benutzer_id int(11) DEFAULT '0' NOT NULL, PRIMARY KEY (gesuchnr,benutzer_id) -) engine=ISAM; +); replace into t1 (gesuchnr,benutzer_id) values (2,1); replace into t1 (gesuchnr,benutzer_id) values (1,1); replace into t1 (gesuchnr,benutzer_id) values (1,1); -alter table t1 engine=myisam; -replace into t1 (gesuchnr,benutzer_id) values (1,1); alter table t1 engine=heap; replace into t1 (gesuchnr,benutzer_id) values (1,1); drop table t1; diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index 1f2fb5056ed..321e5008035 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -31,6 +31,7 @@ xa end 'testa','testb'; connect (con1,localhost,,,); connection con1; +# gtrid [ , bqual [ , formatID ] ] xa start 0x7465737462, 0x2030405060, 0xb; insert t1 values (40); xa end 'testb',' 0@P`',11; diff --git a/mysys/my_sync.c b/mysys/my_sync.c index bd372f03c87..bfaf09ce402 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -27,7 +27,14 @@ my_flags Flags (now only MY_WME is supported) NOTE - If file system supports its, only file data is synced, not inode date + If file system supports its, only file data is synced, not inode data. + + MY_IGNORE_BADFD is useful when fd is "volatile" - not protected by a + mutex. In this case by the time of fsync(), fd may be already closed by + another thread, or even reassigned to a different file. With this flag - + MY_IGNORE_BADFD - such a situation will not be considered an error. + (which is correct behaviour, if we know that the other thread synced the + file before closing) RETURN 0 ok @@ -55,10 +62,15 @@ int my_sync(File fd, myf my_flags) if (res) { - if (!(my_errno= errno)) - my_errno= -1; /* Unknown error */ - if (my_flags & MY_WME) + int er= errno; + if (!(my_errno= er)) + my_errno= -1; /* Unknown error */ + if (my_flags & MY_IGNORE_BADFD && + (er == EBADF || er == EINVAL || er == EROFS)) + res= 0; + else if (my_flags & MY_WME) my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno); } DBUG_RETURN(res); -} /* my_read */ +} /* my_sync */ + diff --git a/sql/handler.cc b/sql/handler.cc index fd9ec7cf423..3181e5754de 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -25,10 +25,6 @@ #include "ha_heap.h" #include "ha_myisam.h" #include "ha_myisammrg.h" -#ifdef HAVE_ISAM -#include "ha_isam.h" -#include "ha_isammrg.h" -#endif #ifdef HAVE_BERKELEY_DB #include "ha_berkeley.h" #endif diff --git a/sql/log.cc b/sql/log.cc index 9af70a4d527..1d6bb4cdf41 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1531,18 +1531,20 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, return 0; } - -inline bool sync_binlog(IO_CACHE *cache) +bool MYSQL_LOG::flush_and_sync() { - if (sync_binlog_period == ++sync_binlog_counter && sync_binlog_period) + int err=0, fd=log_file.file; + safe_mutex_assert_owner(&LOCK_log); + if (flush_io_cache(&log_file)) + return 1; + if (++sync_binlog_counter >= sync_binlog_period && sync_binlog_period) { sync_binlog_counter= 0; - return my_sync(cache->file, MYF(MY_WME)); + err=my_sync(fd, MYF(MY_WME)); } - return 0; + return err; } - /* Write an event to the binary log */ @@ -1675,8 +1677,8 @@ bool MYSQL_LOG::write(Log_event *event_info) } } - /* - Write the SQL command + /* + Write the SQL command */ if (event_info->write(file)) @@ -1684,8 +1686,10 @@ bool MYSQL_LOG::write(Log_event *event_info) if (file == &log_file) // we are writing to the real log (disk) { - if (flush_io_cache(file) || sync_binlog(file)) + if (flush_and_sync()) goto err; + signal_update(); + rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); } error=0; @@ -1698,15 +1702,9 @@ err: my_error(ER_ERROR_ON_WRITE, MYF(0), name, errno); write_error=1; } - if (file == &log_file) - { - signal_update(); - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); - } } pthread_mutex_unlock(&LOCK_log); - DBUG_RETURN(error); } @@ -1813,7 +1811,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event) if (commit_event->write(&log_file)) goto err; DBUG_skip_commit: - if (flush_io_cache(&log_file) || sync_binlog(&log_file)) + if (flush_and_sync()) goto err; DBUG_EXECUTE_IF("half_binlogged_transaction", abort();); if (cache->error) // Error on read @@ -1983,26 +1981,26 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, SYNOPSIS wait_for_update() thd Thread variable - master_or_slave If 0, the caller is the Binlog_dump thread from master; + is_slave If 0, the caller is the Binlog_dump thread from master; if 1, the caller is the SQL thread from the slave. This influences only thd->proc_info. NOTES One must have a lock on LOCK_log before calling this function. - This lock will be freed before return! That's required by + This lock will be released before return! That's required by THD::enter_cond() (see NOTES in sql_class.h). */ -void MYSQL_LOG::wait_for_update(THD* thd, bool master_or_slave) +void MYSQL_LOG::wait_for_update(THD* thd, bool is_slave) { const char *old_msg; DBUG_ENTER("wait_for_update"); old_msg= thd->enter_cond(&update_cond, &LOCK_log, - master_or_slave ? + is_slave ? "Has read all relay log; waiting for the slave I/O " - "thread to update it" : + "thread to update it" : "Has sent all binlog to slave; waiting for binlog " - "to be updated"); + "to be updated"); pthread_cond_wait(&update_cond, &LOCK_log); thd->exit_cond(old_msg); DBUG_VOID_RETURN; @@ -2051,7 +2049,12 @@ void MYSQL_LOG::close(uint exiting) my_pwrite(log_file.file, &flags, 1, offset, MYF(0)); } - if (my_close(log_file.file,MYF(0)) < 0 && ! write_error) + if (my_sync(log_file.file,MYF(MY_WME)) && ! write_error) + { + write_error=1; + sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); + } + if (my_close(log_file.file,MYF(MY_WME)) && ! write_error) { write_error=1; sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno); @@ -2945,8 +2948,10 @@ int TC_LOG_BINLOG::log(THD *thd, my_xid xid) void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid) { - if (thread_safe_dec_and_test(prepared_xids, &LOCK_prep_xids)) + pthread_mutex_lock(&LOCK_prep_xids); + if (--prepared_xids == 0) pthread_cond_signal(&COND_prep_xids); + pthread_mutex_unlock(&LOCK_prep_xids); rotate_and_purge(0); // as ::write() did not rotate } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 7e4c6675e45..b92443f7e15 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1126,10 +1126,6 @@ extern MY_BITMAP temp_pool; extern String my_empty_string; extern const String my_null_string; extern SHOW_VAR init_vars[],status_vars[], internal_vars[]; -extern SHOW_COMP_OPTION have_isam; -extern SHOW_COMP_OPTION have_innodb; -extern SHOW_COMP_OPTION have_berkeley_db; -extern SHOW_COMP_OPTION have_ndbcluster; extern struct system_variables global_system_variables; extern struct system_variables max_system_variables; extern struct system_status_var global_status_var; @@ -1150,12 +1146,13 @@ extern struct my_option my_long_options[]; extern SHOW_COMP_OPTION have_isam, have_innodb, have_berkeley_db; extern SHOW_COMP_OPTION have_example_db, have_archive_db, have_csv_db; extern SHOW_COMP_OPTION have_federated_db; +extern SHOW_COMP_OPTION have_blackhole_db; +extern SHOW_COMP_OPTION have_ndbcluster; extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink; -extern SHOW_COMP_OPTION have_query_cache, have_berkeley_db, have_innodb; +extern SHOW_COMP_OPTION have_query_cache; extern SHOW_COMP_OPTION have_geometry, have_rtree_keys; extern SHOW_COMP_OPTION have_crypt; extern SHOW_COMP_OPTION have_compress; -extern SHOW_COMP_OPTION have_blackhole_db; #ifndef __WIN__ extern pthread_t signal_thread; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 95de170b99d..ee95e00e0ee 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -30,9 +30,6 @@ #include "ha_innodb.h" #endif #include "ha_myisam.h" -#ifdef HAVE_ISAM -#include "ha_isam.h" -#endif #ifdef HAVE_NDBCLUSTER_DB #include "ha_ndbcluster.h" #endif @@ -47,11 +44,6 @@ #else #define OPT_BDB_DEFAULT 0 #endif -#ifdef HAVE_ISAM_DB -#define OPT_ISAM_DEFAULT 1 -#else -#define OPT_ISAM_DEFAULT 0 -#endif #ifdef HAVE_NDBCLUSTER_DB #define OPT_NDBCLUSTER_DEFAULT 0 #if defined(NOT_ENOUGH_TESTED) \ @@ -64,7 +56,6 @@ #define OPT_NDBCLUSTER_DEFAULT 0 #endif -#include #include #include #include @@ -4342,7 +4333,7 @@ Disable with --skip-bdb (will save memory).", "Don't try to recover Berkeley DB tables on start.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"bdb-no-sync", OPT_BDB_NOSYNC, - "Disable synchronously flushing logs. This option is deprecated, use --skip-sync-bdb-logs or sync-bdb-logs=0 instead", + "This option is deprecated, use --skip-sync-bdb-logs instead", // (gptr*) &opt_sync_bdb_logs, (gptr*) &opt_sync_bdb_logs, 0, GET_BOOL, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"bdb-shared-data", OPT_BDB_SHARED, @@ -4551,9 +4542,8 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, (gptr*) &global_system_variables.innodb_support_xa, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, #endif /* End HAVE_INNOBASE_DB */ - {"isam", OPT_ISAM, "Enable ISAM (if this version of MySQL supports it). \ -Disable with --skip-isam.", - (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, OPT_ISAM_DEFAULT, 0, 0, + {"isam", OPT_ISAM, "Obsolete. ISAM storage engine is no longer supported.", + (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"language", 'L', "Client error messages in given language. May be given as a full path.", @@ -5469,36 +5459,35 @@ The minimum value for this variable is 4096.", 1, 0}, #ifdef HAVE_BERKELEY_DB {"sync-bdb-logs", OPT_BDB_SYNC, - "Synchronously flush logs. Enabled by default", + "Synchronously flush Berkeley DB logs. Enabled by default", (gptr*) &opt_sync_bdb_logs, (gptr*) &opt_sync_bdb_logs, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, #endif /* HAVE_BERKELEY_DB */ {"sync-binlog", OPT_SYNC_BINLOG, - "Sync the binlog to disk after every #th event. \ -#=0 (the default) does no sync. Syncing slows MySQL down", - (gptr*) &sync_binlog_period, - (gptr*) &sync_binlog_period, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1, - 0}, + "Synchronously flush binary log to disk after every #th event. " + "Use 0 (default) to disable synchronous flushing.", + (gptr*) &sync_binlog_period, (gptr*) &sync_binlog_period, 0, GET_ULONG, + REQUIRED_ARG, 1, 0, ~0L, 0, 1, 0}, + {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.", + (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, + 0, 0, 0, 0}, #ifdef DOES_NOTHING_YET {"sync-replication", OPT_SYNC_REPLICATION, - "Enable synchronous replication", + "Enable synchronous replication.", (gptr*) &global_system_variables.sync_replication, (gptr*) &global_system_variables.sync_replication, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 1, 0, 1, 0}, {"sync-replication-slave-id", OPT_SYNC_REPLICATION_SLAVE_ID, - "Synchronous replication is wished for this slave", + "Synchronous replication is wished for this slave.", (gptr*) &global_system_variables.sync_replication_slave_id, (gptr*) &global_system_variables.sync_replication_slave_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1, 0}, {"sync-replication-timeout", OPT_SYNC_REPLICATION_TIMEOUT, - "Synchronous replication timeout", + "Synchronous replication timeout.", (gptr*) &global_system_variables.sync_replication_timeout, (gptr*) &global_system_variables.sync_replication_timeout, 0, GET_ULONG, REQUIRED_ARG, 10, 0, ~0L, 0, 1, 0}, #endif - {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default", - (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, - 0, 0, 0, 0}, {"table_cache", OPT_TABLE_CACHE, "The number of open tables for all threads.", (gptr*) &table_cache_size, (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 512*1024L, @@ -5962,11 +5951,7 @@ static void mysql_init_variables(void) #else have_innodb=SHOW_OPTION_NO; #endif -#ifdef HAVE_ISAM - have_isam=SHOW_OPTION_YES; -#else have_isam=SHOW_OPTION_NO; -#endif #ifdef HAVE_EXAMPLE_DB have_example_db= SHOW_OPTION_YES; #else @@ -6375,9 +6360,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_error_log= 0; // Force logs to stdout break; case (int) OPT_FLUSH: -#ifdef HAVE_ISAM - nisam_flush=1; -#endif myisam_flush=1; flush_time=0; // No auto flush break; @@ -6482,14 +6464,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), have_berkeley_db= SHOW_OPTION_YES; else have_berkeley_db= SHOW_OPTION_DISABLED; -#endif - break; - case OPT_ISAM: -#ifdef HAVE_ISAM - if (opt_isam) - have_isam= SHOW_OPTION_YES; - else - have_isam= SHOW_OPTION_DISABLED; #endif break; case OPT_NDBCLUSTER: diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 44e2f5ee9f2..9920d89519e 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -42,7 +42,6 @@ #include "mysql_priv.h" #include -#include #include "sql_select.h" #ifndef EXTRA_DEBUG @@ -51,7 +50,7 @@ #endif /* - Convert double value to #rows. Currently this does floor(), and we + Convert double value to #rows. Currently this does floor(), and we might consider using round() instead. */ #define double2rows(x) ((ha_rows)(x)) diff --git a/sql/set_var.cc b/sql/set_var.cc index 457df3f2947..3523e444216 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -954,9 +954,11 @@ struct show_var_st init_vars[]= { {"sql_warnings", (char*) &sys_sql_warnings, SHOW_BOOL}, #ifdef HAVE_REPLICATION {sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period, SHOW_SYS}, +#ifdef DOES_NOTHING_YET {sys_sync_replication.name, (char*) &sys_sync_replication, SHOW_SYS}, {sys_sync_replication_slave_id.name, (char*) &sys_sync_replication_slave_id,SHOW_SYS}, {sys_sync_replication_timeout.name, (char*) &sys_sync_replication_timeout,SHOW_SYS}, +#endif #endif {sys_sync_frm.name, (char*) &sys_sync_frm, SHOW_SYS}, #ifdef HAVE_TZNAME @@ -2495,14 +2497,6 @@ bool sys_var_sync_binlog_period::update(THD *thd, set_var *var) { pthread_mutex_t *lock_log= mysql_bin_log.get_log_lock(); sync_binlog_period= (ulong) var->save_result.ulonglong_value; - /* - Must reset the counter otherwise it may already be beyond the new period - and so the new period will not be taken into account. Need mutex otherwise - might be cancelled by a simultanate ++ in MYSQL_LOG::write(). - */ - pthread_mutex_lock(lock_log); - sync_binlog_counter= 0; - pthread_mutex_unlock(lock_log); return 0; } #endif /* HAVE_REPLICATION */ @@ -2522,7 +2516,7 @@ bool sys_var_rand_seed2::update(THD *thd, set_var *var) bool sys_var_thd_time_zone::check(THD *thd, set_var *var) { - char buff[MAX_TIME_ZONE_NAME_LENGTH]; + char buff[MAX_TIME_ZONE_NAME_LENGTH]; String str(buff, sizeof(buff), &my_charset_latin1); String *res= var->value->val_str(&str); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4750fe1386f..b0f2930758e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -25,7 +25,6 @@ #include #include #include -#include #ifdef __WIN__ #include #endif diff --git a/sql/sql_class.h b/sql/sql_class.h index 6d6ac810fbf..123ecdfaa89 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -327,6 +327,7 @@ public: bool is_active(const char* log_file_name); int update_log_index(LOG_INFO* linfo, bool need_update_threads); void rotate_and_purge(uint flags); + bool flush_and_sync(); int purge_logs(const char *to_log, bool included, bool need_mutex, bool need_update_threads, ulonglong *decrease_log_space); @@ -1283,18 +1284,18 @@ public: pthread_mutex_unlock(&LOCK_delete); } void close_active_vio(); -#endif +#endif void awake(THD::killed_state state_to_set); /* For enter_cond() / exit_cond() to work the mutex must be got before - enter_cond() (in 4.1 an assertion will soon ensure this); this mutex is - then released by exit_cond(). Use must be: - lock mutex; enter_cond(); your code; exit_cond(). + enter_cond(); this mutex is then released by exit_cond(). + Usage must be: lock mutex; enter_cond(); your code; exit_cond(). */ inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, const char* msg) { const char* old_msg = proc_info; + safe_mutex_assert_owner(mutex); mysys_var->current_mutex = mutex; mysys_var->current_cond = cond; proc_info = msg; From 8d6427659fb592211b144a0d73e7b8ea7120cf8e Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Tue, 5 Apr 2005 15:13:14 +0300 Subject: [PATCH 29/83] InnoDB: Disable an assertion that fails on old data due to Bug #9526 --- innobase/row/row0sel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 09a6f1eacff..e3f31c116fa 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2364,7 +2364,9 @@ row_sel_field_store_in_mysql_format( ut_a(templ->mbmaxlen > templ->mbminlen || templ->mysql_col_len == len); - ut_a(!templ->mbmaxlen + /* The following assertion would fail for old tables + containing UTF-8 ENUM columns due to Bug #9526. */ + ut_ad(!templ->mbmaxlen || !(templ->mysql_col_len % templ->mbmaxlen)); ut_a(len * templ->mbmaxlen >= templ->mysql_col_len); From 71811298b9387b4af58baf762b3e5651d93d93d4 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 5 Apr 2005 14:46:18 +0200 Subject: [PATCH 30/83] sql/item.cc after merge fix sql/mysqld.cc too early for sync-binlog=1 by default :) --- sql/item.cc | 2 +- sql/mysqld.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 1572efb0f23..d3abc40eb29 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1496,7 +1496,7 @@ longlong Item_string::val_int() char *org_end= end; CHARSET_INFO *cs= str_value.charset(); - tmp= (*(cs->cset->my_strtoll10))(cs, str_value.ptr(), &end, &err); + tmp= (*(cs->cset->strtoll10))(cs, str_value.ptr(), &end, &err); /* TODO: Give error if we wanted a signed integer and we got an unsigned one diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ba149e5cee6..ecf2094eb18 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5467,7 +5467,7 @@ The minimum value for this variable is 4096.", "Synchronously flush binary log to disk after every #th event. " "Use 0 (default) to disable synchronous flushing.", (gptr*) &sync_binlog_period, (gptr*) &sync_binlog_period, 0, GET_ULONG, - REQUIRED_ARG, 1, 0, ~0L, 0, 1, 0}, + REQUIRED_ARG, 0, 0, ~0L, 0, 1, 0}, {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.", (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, From 3c3defaa0a50ef6a21c803bd9145473890a92967 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 5 Apr 2005 15:16:15 +0200 Subject: [PATCH 31/83] add changeset key to the bk commit mail --- BitKeeper/triggers/post-commit | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index d2a4f9153b2..4c28b408658 100755 --- a/BitKeeper/triggers/post-commit +++ b/BitKeeper/triggers/post-commit @@ -27,6 +27,7 @@ then fi CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet` +CSETKEY=`bk -R prs -r+ -h -d':KEY:' ChangeSet` BUG=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Bb][Uu][Gg] *# *\([0-9][0-9]*\).*$/\1/p'` if [ "$BUG" = "" ] @@ -51,6 +52,7 @@ List-ID: From: $FROM To: $TO Subject: bk commit - $VERSION tree ($CHANGESET)$BS +X-CSetKey: <$CSETKEY> $BH EOF bk changes -v -r+ @@ -67,6 +69,7 @@ List-ID: From: $FROM To: $INTERNALS Subject: bk commit into $VERSION tree ($CHANGESET)$BS +X-CSetKey: <$CSETKEY> $BH Below is the list of changes that have just been committed into a local $VERSION repository of $USER. When $USER does a push these changes will From 7f2a12bbbfe3b8b029cafcb000e066a5d7780aee Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 5 Apr 2005 15:36:52 +0200 Subject: [PATCH 32/83] fix broken mix_innodb_myisam_binlog.test --- mysql-test/t/mix_innodb_myisam_binlog.test | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test index cf575ab1e52..0641acb552f 100644 --- a/mysql-test/t/mix_innodb_myisam_binlog.test +++ b/mysql-test/t/mix_innodb_myisam_binlog.test @@ -29,7 +29,7 @@ insert into t2 select * from t1; commit; --replace_column 5 # ---replace_result "xid=12" "xid=7" +--replace_result "xid=15" "xid=8" show binlog events from 98; delete from t1; @@ -58,7 +58,7 @@ rollback to savepoint my_savepoint; commit; --replace_column 5 # ---replace_result "xid=45" "xid=24" +--replace_result "xid=48" "xid=25" show binlog events from 98; delete from t1; @@ -76,7 +76,7 @@ commit; select a from t1 order by a; # check that savepoints work :) --replace_column 5 # ---replace_result "xid=67" "xid=36" +--replace_result "xid=70" "xid=37" show binlog events from 98; # and when ROLLBACK is not explicit? @@ -109,7 +109,7 @@ insert into t1 values(9); insert into t2 select * from t1; --replace_column 5 # ---replace_result "xid=116" "xid=59" +--replace_result "xid=119" "xid=60" show binlog events from 98; # Check that when the query updat1ng the MyISAM table is the first in the @@ -122,13 +122,13 @@ insert into t1 values(10); # first make t1 non-empty begin; insert into t2 select * from t1; --replace_column 5 # ---replace_result "xid=130" "xid=65" +--replace_result "xid=133" "xid=66" show binlog events from 98; insert into t1 values(11); commit; --replace_column 5 # ---replace_result "xid=130" "xid=65" "xid=133" "xid=67" +--replace_result "xid=133" "xid=66" "xid=136" "xid=68" show binlog events from 98; @@ -147,7 +147,7 @@ insert into t2 select * from t1; commit; --replace_column 5 # ---replace_result "xid=152" "xid=77" +--replace_result "xid=155" "xid=78" show binlog events from 98; delete from t1; @@ -175,7 +175,7 @@ rollback to savepoint my_savepoint; commit; --replace_column 5 # ---replace_result "xid=184" "xid=93" +--replace_result "xid=187" "xid=94" show binlog events from 98; delete from t1; @@ -193,7 +193,7 @@ commit; select a from t1 order by a; # check that savepoints work :) --replace_column 5 # ---replace_result "xid=205" "xid=104" +--replace_result "xid=208" "xid=105" show binlog events from 98; # Test for BUG#5714, where a MyISAM update in the transaction used to From b18ca48c47ed04a7414ebb0e48f3071838539db5 Mon Sep 17 00:00:00 2001 From: "pem@mysql.comhem.se" <> Date: Tue, 5 Apr 2005 15:49:10 +0200 Subject: [PATCH 33/83] Additional fix for BUG#5907: Traditional mode: invalid value can be inserted via a stored procedure ... make the handler catch too. --- mysql-test/r/strict.result | 3 ++- mysql-test/t/strict.test | 1 - sql/sp_head.cc | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index c4d860c5c77..99ea0d577da 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -1180,7 +1180,8 @@ Note 1305 PROCEDURE t1 does not exist create procedure t1 () begin declare exit handler for sqlexception select'a'; insert into t1 values (200); end;| call t1(); -ERROR 22003: Out of range value adjusted for column 'col1' at row 1 +a +a select * from t1; col1 drop procedure t1; diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index b5d234b7bea..6b7ce1a8f9e 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -1040,7 +1040,6 @@ delimiter |; create procedure t1 () begin declare exit handler for sqlexception select'a'; insert into t1 values (200); end;| delimiter ;| ---error 1264 call t1(); select * from t1; drop procedure t1; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 89c4b2dbaac..63f67959f33 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -561,7 +561,10 @@ sp_head::execute(THD *thd) // Check if an exception has occurred and a handler has been found // Note: We havo to check even if ret==0, since warnings (and some // errors don't return a non-zero value. - if (!thd->killed && ctx) + // We also have to check even if thd->killed != 0, since some + // errors return with this even when a handler has been found + // (e.g. "bad data"). + if (ctx) { uint hf; @@ -579,6 +582,7 @@ sp_head::execute(THD *thd) ctx->clear_handler(); ctx->in_handler= TRUE; thd->clear_error(); + thd->killed= THD::NOT_KILLED; continue; } } From 70482c41274466bd352cc44d946f882c848d7cc3 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Tue, 5 Apr 2005 15:56:43 +0200 Subject: [PATCH 34/83] Fix Bug #9517 Condition pushdown to storage engine does not work for update/delete, post review fix, removed quick constraint --- sql/records.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/records.cc b/sql/records.cc index 28a8e9a9aa5..cfb7cb3d065 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -132,7 +132,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, if (thd->variables.engine_condition_pushdown && select && select->cond && select->cond->used_tables() & table->map && - !(select->quick || table->file->pushed_cond)) + !table->file->pushed_cond) table->file->cond_push(select->cond); DBUG_VOID_RETURN; From d6062ef9b530332489f3a4738f1fea468498894c Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 5 Apr 2005 16:39:40 +0200 Subject: [PATCH 35/83] removed a reference to non-existing file --- .bzrignore | 2 ++ configure.in | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.bzrignore b/.bzrignore index 02a97d7d1af..eae47b882d0 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1107,3 +1107,5 @@ vio/test-sslclient vio/test-sslserver vio/viotest-ssl VC++Files/client/mysql_amd64.dsp +client/mysqltestmanager-pwgen +client/mysqltestmanagerc diff --git a/configure.in b/configure.in index c3c792e7339..c7e93c9676a 100644 --- a/configure.in +++ b/configure.in @@ -41,7 +41,6 @@ sinclude(config/ac-macros/ha_blackhole.m4) sinclude(config/ac-macros/ha_example.m4) sinclude(config/ac-macros/ha_federated.m4) sinclude(config/ac-macros/ha_innodb.m4) -sinclude(config/ac-macros/ha_isam.m4) sinclude(config/ac-macros/ha_ndbcluster.m4) sinclude(config/ac-macros/ha_tina.m4) sinclude(config/ac-macros/large_file.m4) From a3e6b30a89a21821b5b55144fa0c5f95f5ae3a04 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 5 Apr 2005 17:56:40 +0300 Subject: [PATCH 36/83] handler.cc, ha_innodb.cc: Fix Bug #8650 : InnoDB does not rollback SQL statement at an error --- sql/ha_innodb.cc | 56 ++++++++++++++++++++++++++++++++++-------------- sql/handler.cc | 6 +++--- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 5365eee8f38..cfc649a5963 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -748,17 +748,37 @@ ha_innobase::update_thd( } /************************************************************************* -Registers the InnoDB transaction in MySQL, to receive commit/rollback -events. This function must be called every time InnoDB starts a -transaction internally. */ -static +Registers that InnoDB takes part in an SQL statement, so that MySQL knows to +roll back the statement if the statement results in an error. This MUST be +called for every SQL statement that may be rolled back by MySQL. Calling this +several times to register the same statement is allowed, too. */ +inline void -register_trans( -/*===========*/ - THD* thd) /* in: thd to use the handle */ +innobase_register_stmt( +/*===================*/ + THD* thd) /* in: MySQL thd (connection) object */ { - /* Register the start of the statement */ + /* Register the statement */ trans_register_ha(thd, FALSE, &innobase_hton); +} + +/************************************************************************* +Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows +to call the InnoDB prepare and commit, or rollback for the transaction. This +MUST be called for every transaction for which the user may call commit or +rollback. Calling this several times to register the same transaction is +allowed, too. +This function also registers the current SQL statement. */ +inline +void +innobase_register_trx_and_stmt( +/*===========================*/ + THD* thd) /* in: MySQL thd (connection) object */ +{ + /* NOTE that actually innobase_register_stmt() registers also + the transaction in the AUTOCOMMIT=1 mode. */ + + innobase_register_stmt(thd); if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { @@ -914,7 +934,7 @@ innobase_query_caching_of_table_permitted( if (trx->active_trans == 0) { - register_trans(thd); + innobase_register_trx_and_stmt(thd); trx->active_trans = 1; } @@ -1030,7 +1050,7 @@ ha_innobase::init_table_handle_for_HANDLER(void) if (prebuilt->trx->active_trans == 0) { - register_trans(current_thd); + innobase_register_trx_and_stmt(current_thd); prebuilt->trx->active_trans = 1; } @@ -1421,7 +1441,7 @@ innobase_start_trx_and_assign_read_view( if (trx->active_trans == 0) { - register_trans(current_thd); + innobase_register_trx_and_stmt(current_thd); trx->active_trans = 1; } @@ -5544,9 +5564,11 @@ ha_innobase::start_stmt( /* Set the MySQL flag to mark that there is an active transaction */ if (trx->active_trans == 0) { - register_trans(thd); + innobase_register_trx_and_stmt(thd); trx->active_trans = 1; - } + } else { + innobase_register_stmt(thd); + } return(0); } @@ -5616,9 +5638,11 @@ ha_innobase::external_lock( transaction */ if (trx->active_trans == 0) { - register_trans(thd); + innobase_register_trx_and_stmt(thd); trx->active_trans = 1; - } + } else if (trx->n_mysql_tables_in_use == 0) { + innobase_register_stmt(thd); + } trx->n_mysql_tables_in_use++; prebuilt->mysql_has_locked = TRUE; @@ -5780,7 +5804,7 @@ ha_innobase::transactional_table_lock( /* Set the MySQL flag to mark that there is an active transaction */ if (trx->active_trans == 0) { - register_trans(thd); + innobase_register_trx_and_stmt(thd); trx->active_trans = 1; } diff --git a/sql/handler.cc b/sql/handler.cc index 3eead37482b..7cd2fd303f0 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -520,14 +520,14 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg) else trans= &thd->transaction.stmt; -#ifndef DBUG_OFF handlerton **ht=trans->ht; while (*ht) { - DBUG_ASSERT(*ht != ht_arg); + if (*ht == ht_arg) + DBUG_VOID_RETURN; /* already registered, return */ ht++; } -#endif + trans->ht[trans->nht++]=ht_arg; trans->no_2pc|=(ht_arg->prepare==0); if (thd->transaction.xid.is_null()) From 42277bdd2fa842f281abdc9a6292d8be92d490d8 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 5 Apr 2005 18:42:34 +0200 Subject: [PATCH 37/83] Per Heikki's request make trans_register_ha tolerant to multiple registrations --- sql/handler.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 3eead37482b..96fe3937198 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -505,10 +505,16 @@ void ha_close_connection(THD* thd) "beginning of transaction" and "beginning of statement"). Only storage engines registered for the transaction/statement will know when to commit/rollback it. + + NOTE + trans_register_ha is idempotent - storage engine may register many + times per transaction. + */ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg) { THD_TRANS *trans; + handlerton **ht; DBUG_ENTER("trans_register_ha"); DBUG_PRINT("enter",("%s", all ? "all" : "stmt")); @@ -520,15 +526,12 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg) else trans= &thd->transaction.stmt; -#ifndef DBUG_OFF - handlerton **ht=trans->ht; - while (*ht) - { - DBUG_ASSERT(*ht != ht_arg); - ht++; - } -#endif + for (ht=trans->ht; *ht; ht++) + if (*ht == ht_arg) + DBUG_VOID_RETURN; + trans->ht[trans->nht++]=ht_arg; + DBUG_ASSERT(*ht == ht_arg); trans->no_2pc|=(ht_arg->prepare==0); if (thd->transaction.xid.is_null()) thd->transaction.xid.set(thd->query_id); From 127afff8c87cf8d6a56de799a6b7d5ad2a20d5bd Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Tue, 5 Apr 2005 13:01:42 -0700 Subject: [PATCH 38/83] Remove references to result.es files --- mysql-test/Makefile.am | 3 +-- scripts/make_binary_distribution.sh | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 294c135bcf3..1325b90631f 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -51,7 +51,7 @@ dist-hook: -$(INSTALL_DATA) $(srcdir)/t/*.disabled $(distdir)/t $(INSTALL_DATA) $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t $(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include - $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.result.es $(srcdir)/r/*.require $(distdir)/r + $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.000001 $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data @@ -71,7 +71,6 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/t/*.sh $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.slave-mi $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/r/*.result $(DESTDIR)$(testdir)/r - $(INSTALL_DATA) $(srcdir)/r/*.result.es $(DESTDIR)$(testdir)/r $(INSTALL_DATA) $(srcdir)/r/*.require $(DESTDIR)$(testdir)/r $(INSTALL_DATA) $(srcdir)/include/*.inc $(DESTDIR)$(testdir)/include $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 6ebe05fe116..a1c380780b0 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -225,7 +225,7 @@ $CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \ $BASE/mysql-test/std_data $CP mysql-test/t/*.test mysql-test/t/*.disabled mysql-test/t/*.opt \ mysql-test/t/*.slave-mi mysql-test/t/*.sh $BASE/mysql-test/t -$CP mysql-test/r/*.result mysql-test/r/*.result.es mysql-test/r/*.require \ +$CP mysql-test/r/*.result mysql-test/r/*.require \ $BASE/mysql-test/r if [ $BASE_SYSTEM != "netware" ] ; then From 1dd12e9d04cfe57594c46b85b5a3e0a3cb564d3f Mon Sep 17 00:00:00 2001 From: "jani@ua141d10.elisa.omakaista.fi" <> Date: Tue, 5 Apr 2005 23:14:56 +0300 Subject: [PATCH 39/83] Some of the argument place holders were not quite correct compared to the argument type. Fixed also some float() casts to double() as query_id is now actually longlong type. Related to Bug#9646. --- sql/sql_parse.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 69126e35554..693229c5a24 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1912,12 +1912,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif ulong uptime = (ulong) (thd->start_time - start_time); sprintf((char*) buff, - "Uptime: %ld Threads: %d Questions: %lu Slow queries: %lu Opens: %ld Flush tables: %ld Open tables: %u Queries per second avg: %.3f", + "Uptime: %lu Threads: %d Questions: %lu Slow queries: %lu Opens: %lu Flush tables: %lu Open tables: %u Queries per second avg: %.3f", uptime, (int) thread_count, (ulong) thd->query_id, (ulong) thd->status_var.long_query_count, thd->status_var.opened_tables, refresh_version, cached_tables(), - uptime ? (float)thd->query_id/(float)uptime : 0); + (uptime ? (ulonglong2double(thd->query_id) / (double) uptime) : + (double) 0)); #ifdef SAFEMALLOC if (sf_malloc_cur_memory) // Using SAFEMALLOC sprintf(strend(buff), " Memory in use: %ldK Max memory used: %ldK", From 2f398fc3aea34dca70fb4ec4220ff3c940f72fd8 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Tue, 5 Apr 2005 20:55:06 -0700 Subject: [PATCH 40/83] Update tests after merge of bug fix. --- mysql-test/r/null.result | 2 +- mysql-test/r/show_check.result | 16 +++---- mysql-test/r/strict.result | 82 +++++++++++++++++----------------- mysql-test/t/null.test | 2 +- mysql-test/t/show_check.test | 2 +- 5 files changed, 52 insertions(+), 52 deletions(-) diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 806e2b6f254..c2b925072dd 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -88,7 +88,7 @@ b ifnull(t2.b,"this is null") NULL this is null NULL this is null drop table t1; -CREATE TABLE t1 (a varchar(16) NOT NULL default '', b smallint(6) NOT NULL default '', c datetime NOT NULL default '0000-00-00 00:00:00', d smallint(6) NOT NULL default 0); +CREATE TABLE t1 (a varchar(16) NOT NULL default '', b smallint(6) NOT NULL default 0, c datetime NOT NULL default '0000-00-00 00:00:00', d smallint(6) NOT NULL default 0); INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55"; Warnings: Warning 1265 Data truncated for column 'd' at row 1 diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 7c34481b519..add4e91c725 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -195,7 +195,7 @@ h float(3,2) NULL YES NULL select,insert,update,references i float(3,0) NULL YES NULL select,insert,update,references drop table t1; create table t1 ( -type_bool bool not null, +type_bool bool not null default 0, type_tiny tinyint not null auto_increment primary key, type_short smallint(3), type_mediumint mediumint, @@ -206,9 +206,9 @@ empty_char char(0), type_char char(2), type_varchar varchar(10), type_timestamp timestamp not null, -type_date date not null, -type_time time not null, -type_datetime datetime not null, +type_date date not null default '0000-00-00', +type_time time not null default '00:00:00', +type_datetime datetime not null default '0000-00-00 00:00:00', type_year year, type_enum enum ('red', 'green', 'blue'), type_set enum ('red', 'green', 'blue'), @@ -221,7 +221,7 @@ index(type_short) show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `type_bool` tinyint(1) NOT NULL, + `type_bool` tinyint(1) NOT NULL default '0', `type_tiny` tinyint(4) NOT NULL auto_increment, `type_short` smallint(3) default NULL, `type_mediumint` mediumint(9) default NULL, @@ -232,9 +232,9 @@ t1 CREATE TABLE `t1` ( `type_char` char(2) default NULL, `type_varchar` varchar(10) default NULL, `type_timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, - `type_date` date NOT NULL, - `type_time` time NOT NULL, - `type_datetime` datetime NOT NULL, + `type_date` date NOT NULL default '0000-00-00', + `type_time` time NOT NULL default '00:00:00', + `type_datetime` datetime NOT NULL default '0000-00-00 00:00:00', `type_year` year(4) default NULL, `type_enum` enum('red','green','blue') default NULL, `type_set` enum('red','green','blue') default NULL, diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 5e1768a207e..7d1b6b67fd2 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -1042,47 +1042,6 @@ col1 col2 3 99 DROP TABLE t1; -SET @@sql_mode = 'traditional'; -CREATE TABLE t1 (i int not null); -INSERT INTO t1 VALUES (); -ERROR HY000: Field 'i' doesn't have a default value -INSERT INTO t1 VALUES (DEFAULT); -ERROR HY000: Field 'i' doesn't have a default value -INSERT INTO t1 VALUES (DEFAULT(i)); -ERROR HY000: Field 'i' doesn't have a default value -ALTER TABLE t1 ADD j int; -INSERT INTO t1 SET j = 1; -ERROR HY000: Field 'i' doesn't have a default value -INSERT INTO t1 SET j = 1, i = DEFAULT; -ERROR HY000: Field 'i' doesn't have a default value -INSERT INTO t1 SET j = 1, i = DEFAULT(i); -ERROR HY000: Field 'i' doesn't have a default value -INSERT INTO t1 VALUES (DEFAULT,1); -ERROR HY000: Field 'i' doesn't have a default value -DROP TABLE t1; -SET @@sql_mode = ''; -CREATE TABLE t1 (i int not null); -INSERT INTO t1 VALUES (); -Warnings: -Warning 1364 Field 'i' doesn't have a default value -INSERT INTO t1 VALUES (DEFAULT); -Warnings: -Warning 1364 Field 'i' doesn't have a default value -INSERT INTO t1 VALUES (DEFAULT(i)); -ERROR HY000: Field 'i' doesn't have a default value -ALTER TABLE t1 ADD j int; -INSERT INTO t1 SET j = 1; -Warnings: -Warning 1364 Field 'i' doesn't have a default value -INSERT INTO t1 SET j = 1, i = DEFAULT; -Warnings: -Warning 1364 Field 'i' doesn't have a default value -INSERT INTO t1 SET j = 1, i = DEFAULT(i); -ERROR HY000: Field 'i' doesn't have a default value -INSERT INTO t1 VALUES (DEFAULT,1); -Warnings: -Warning 1364 Field 'i' doesn't have a default value -DROP TABLE t1; set sql_mode='traditional'; create table t1 (charcol char(255), varcharcol varchar(255), binarycol binary(255), varbinarycol varbinary(255), tinytextcol tinytext, @@ -1232,3 +1191,44 @@ col1 drop procedure t1; drop table t1; set sql_mode=@org_mode; +SET @@sql_mode = 'traditional'; +CREATE TABLE t1 (i int not null); +INSERT INTO t1 VALUES (); +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT); +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT(i)); +ERROR HY000: Field 'i' doesn't have a default value +ALTER TABLE t1 ADD j int; +INSERT INTO t1 SET j = 1; +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 SET j = 1, i = DEFAULT; +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 SET j = 1, i = DEFAULT(i); +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT,1); +ERROR HY000: Field 'i' doesn't have a default value +DROP TABLE t1; +SET @@sql_mode = ''; +CREATE TABLE t1 (i int not null); +INSERT INTO t1 VALUES (); +Warnings: +Warning 1364 Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT); +Warnings: +Warning 1364 Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT(i)); +ERROR HY000: Field 'i' doesn't have a default value +ALTER TABLE t1 ADD j int; +INSERT INTO t1 SET j = 1; +Warnings: +Warning 1364 Field 'i' doesn't have a default value +INSERT INTO t1 SET j = 1, i = DEFAULT; +Warnings: +Warning 1364 Field 'i' doesn't have a default value +INSERT INTO t1 SET j = 1, i = DEFAULT(i); +ERROR HY000: Field 'i' doesn't have a default value +INSERT INTO t1 VALUES (DEFAULT,1); +Warnings: +Warning 1364 Field 'i' doesn't have a default value +DROP TABLE t1; diff --git a/mysql-test/t/null.test b/mysql-test/t/null.test index 934b165f604..4cd20979319 100644 --- a/mysql-test/t/null.test +++ b/mysql-test/t/null.test @@ -59,7 +59,7 @@ drop table t1; # # Test inserting and updating with NULL # -CREATE TABLE t1 (a varchar(16) NOT NULL default '', b smallint(6) NOT NULL default '', c datetime NOT NULL default '0000-00-00 00:00:00', d smallint(6) NOT NULL default 0); +CREATE TABLE t1 (a varchar(16) NOT NULL default '', b smallint(6) NOT NULL default 0, c datetime NOT NULL default '0000-00-00 00:00:00', d smallint(6) NOT NULL default 0); INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55"; UPDATE t1 SET d=1/NULL; UPDATE t1 SET d=NULL; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 0004591288f..558adab5313 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -106,7 +106,7 @@ drop table t1; # Do a create table that tries to cover all types and options # create table t1 ( -type_bool bool not null default false, +type_bool bool not null default 0, type_tiny tinyint not null auto_increment primary key, type_short smallint(3), type_mediumint mediumint, From 0134a2b286e8402932207e9f2c402c28448568bc Mon Sep 17 00:00:00 2001 From: "bar@mysql.com" <> Date: Wed, 6 Apr 2005 11:53:15 +0500 Subject: [PATCH 41/83] Adding a new parameter for well_formed_length to return error. We'll use it for better warnign reporting. --- include/m_ctype.h | 9 ++++++--- ndb/src/ndbapi/NdbIndexOperation.cpp | 4 +++- ndb/src/ndbapi/NdbOperationDefine.cpp | 4 +++- ndb/src/ndbapi/NdbOperationSearch.cpp | 4 +++- sql/field.cc | 15 ++++++++------- sql/sql_yacc.yy | 3 ++- strings/ctype-big5.c | 6 +++++- strings/ctype-mb.c | 9 ++++++--- strings/ctype-simple.c | 6 +++--- strings/ctype-sjis.c | 5 ++++- strings/ctype-ucs2.c | 6 +++--- strings/ctype-ujis.c | 13 +++++++++++-- 12 files changed, 57 insertions(+), 27 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index 26e285b9683..aab39156de1 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -147,7 +147,8 @@ typedef struct my_charset_handler_st uint (*numchars)(struct charset_info_st *, const char *b, const char *e); uint (*charpos)(struct charset_info_st *, const char *b, const char *e, uint pos); uint (*well_formed_len)(struct charset_info_st *, - const char *b,const char *e, uint nchars); + const char *b,const char *e, + uint nchars, int *error); uint (*lengthsp)(struct charset_info_st *, const char *ptr, uint length); uint (*numcells)(struct charset_info_st *, const char *b, const char *e); @@ -341,7 +342,8 @@ int my_wildcmp_8bit(CHARSET_INFO *, uint my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e); uint my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e); uint my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos); -uint my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos); +uint my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e, + uint pos, int *error); int my_mbcharlen_8bit(CHARSET_INFO *, uint c); @@ -359,7 +361,8 @@ int my_wildcmp_mb(CHARSET_INFO *, uint my_numchars_mb(CHARSET_INFO *, const char *b, const char *e); uint my_numcells_mb(CHARSET_INFO *, const char *b, const char *e); uint my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, uint pos); -uint my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e, uint pos); +uint my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e, + uint pos, int *error); uint my_instr_mb(struct charset_info_st *, const char *b, uint b_length, const char *s, uint s_length, diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp index 23af646c4c7..39da9c5f5d0 100644 --- a/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -354,12 +354,14 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo, *************************************************************************/ if ((tOpType == WriteRequest)) { if (!tAttrInfo->m_indexOnly){ + int dummy_error; // invalid data can crash kernel if (cs != NULL && (*cs->cset->well_formed_len)(cs, aValueToWrite, aValueToWrite + sizeInBytes, - sizeInBytes) != sizeInBytes) + sizeInBytes, + &dummy_error) != sizeInBytes) goto equal_error4; Uint32 ahValue; Uint32 sz = totalSizeInWords; diff --git a/ndb/src/ndbapi/NdbOperationDefine.cpp b/ndb/src/ndbapi/NdbOperationDefine.cpp index c4aaffb3119..dfc54133e6c 100644 --- a/ndb/src/ndbapi/NdbOperationDefine.cpp +++ b/ndb/src/ndbapi/NdbOperationDefine.cpp @@ -526,6 +526,7 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, const Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; CHARSET_INFO* cs = tAttrInfo->m_cs; + int dummy_error; // invalid data can crash kernel if (cs != NULL && // fast fix bug#7340 @@ -533,7 +534,8 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, (*cs->cset->well_formed_len)(cs, aValue, aValue + sizeInBytes, - sizeInBytes) != sizeInBytes) { + sizeInBytes, + &dummy_error) != sizeInBytes) { setErrorCodeAbort(744); return -1; } diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp index 28a70abcb9b..97b2393e5ed 100644 --- a/ndb/src/ndbapi/NdbOperationSearch.cpp +++ b/ndb/src/ndbapi/NdbOperationSearch.cpp @@ -226,12 +226,14 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) { if (!tAttrInfo->m_indexOnly){ + int dummy_error; // invalid data can crash kernel if (cs != NULL && (*cs->cset->well_formed_len)(cs, aValueToWrite, aValueToWrite + sizeInBytes, - sizeInBytes) != sizeInBytes) + sizeInBytes, + &dummy_error) != sizeInBytes) goto equal_error4; Uint32 ahValue; const Uint32 sz = totalSizeInWords; diff --git a/sql/field.cc b/sql/field.cc index bf581e62f34..740c027350d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4939,9 +4939,10 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) as well as don't copy a malformed data. */ copy_length= field_charset->cset->well_formed_len(field_charset, - from,from+length, - field_length/ - field_charset->mbmaxlen); + from,from+length, + field_length/ + field_charset->mbmaxlen, + &error); memcpy(ptr,from,copy_length); if (copy_length < field_length) // Append spaces if shorter field_charset->cset->fill(field_charset,ptr+copy_length, @@ -4958,7 +4959,6 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) } if (error) set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1); - return error; } @@ -5577,9 +5577,10 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) the 'min()' call below. */ copy_length= field_charset->cset->well_formed_len(field_charset, - from,from + - min(length, copy_length), - copy_length); + from,from + + min(length, copy_length), + copy_length, + &error); if (copy_length < length) error= 1; Field_blob::store_length(copy_length); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9f25e17b6fd..dcda19a7080 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5032,9 +5032,10 @@ IDENT_sys: if (thd->charset_is_system_charset) { CHARSET_INFO *cs= system_charset_info; + int dummy_error; uint wlen= cs->cset->well_formed_len(cs, $1.str, $1.str+$1.length, - $1.length); + $1.length, &dummy_error); if (wlen < $1.length) { net_printf(YYTHD, ER_INVALID_CHARACTER_STRING, cs->csname, diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index e083d1371ec..07b30205f89 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6278,10 +6278,13 @@ my_mb_wc_big5(CHARSET_INFO *cs __attribute__((unused)), */ static uint my_well_formed_len_big5(CHARSET_INFO *cs __attribute__((unused)), - const char *b, const char *e, uint pos) + const char *b, const char *e, + uint pos, int *error) { const char *b0= b; const char *emb= e - 1; /* Last possible end of an MB character */ + + *error= 0; while (pos && b < e) { if ((uchar) b[0] < 128) @@ -6297,6 +6300,7 @@ uint my_well_formed_len_big5(CHARSET_INFO *cs __attribute__((unused)), else { /* Wrong byte sequence */ + *error= 1; break; } } diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 6cf48291c91..dbe3a24324e 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -264,18 +264,21 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), } -uint my_well_formed_len_mb(CHARSET_INFO *cs, - const char *b, const char *e, uint pos) +uint my_well_formed_len_mb(CHARSET_INFO *cs, const char *b, const char *e, + uint pos, int *error) { const char *b_start= b; - + *error= 0; while (pos) { my_wc_t wc; int mblen; if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0) + { + *error= 1; break; + } b+= mblen; pos--; } diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 080e0b780b7..bd5131b7448 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1093,11 +1093,11 @@ uint my_charpos_8bit(CHARSET_INFO *cs __attribute__((unused)), uint my_well_formed_len_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *start, - const char *end, - uint nchars) + const char *start, const char *end, + uint nchars, int *error) { uint nbytes= (uint) (end-start); + *error= 0; return min(nbytes, nchars); } diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 20f0081888f..35182db3345 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4571,9 +4571,11 @@ uint my_numcells_sjis(CHARSET_INFO *cs __attribute__((unused)), */ static uint my_well_formed_len_sjis(CHARSET_INFO *cs __attribute__((unused)), - const char *b, const char *e, uint pos) + const char *b, const char *e, + uint pos, int *error) { const char *b0= b; + *error= 0; while (pos && b < e) { if ((uchar) b[0] < 128) @@ -4594,6 +4596,7 @@ uint my_well_formed_len_sjis(CHARSET_INFO *cs __attribute__((unused)), else { /* Wrong byte sequence */ + *error= 1; break; } } diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 9c67d1b7846..f5d0721fa9b 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1267,11 +1267,11 @@ uint my_charpos_ucs2(CHARSET_INFO *cs __attribute__((unused)), static uint my_well_formed_len_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *b, - const char *e, - uint nchars) + const char *b, const char *e, + uint nchars, int *error) { uint nbytes= (e-b) & ~ (uint)1; + *error= 0; nchars*= 2; return min(nbytes, nchars); } diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index fc1496df280..612dda2b3eb 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8253,11 +8253,12 @@ my_jisx0212_uni_onechar(int code){ static uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)), - const char *beg, const char *end, uint pos) + const char *beg, const char *end, + uint pos, int *error) { const uchar *b= (uchar *) beg; - for ( ; pos && b < (uchar*) end; pos--, b++) + for ( *error= 0 ; pos && b < (uchar*) end; pos--, b++) { char *chbeg; uint ch= *b; @@ -8267,12 +8268,16 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)), chbeg= (char *) b++; if (b >= (uchar *) end) /* need more bytes */ + { + *error= 1; return chbeg - beg; /* unexpected EOL */ + } if (ch == 0x8E) /* [x8E][xA0-xDF] */ { if (*b >= 0xA0 && *b <= 0xDF) continue; + *error= 1; return chbeg - beg; /* invalid sequence */ } @@ -8280,12 +8285,16 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)), { ch= *b++; if (b >= (uchar*) end) + { + *error= 1; return chbeg - beg; /* unexpected EOL */ + } } if (ch >= 0xA1 && ch <= 0xFE && *b >= 0xA1 && *b <= 0xFE) /* [xA1-xFE][xA1-xFE] */ continue; + *error= 1; return chbeg - beg; /* invalid sequence */ } return b - (uchar *) beg; From 0c2caeb4d82f49dd109a0495ead6242953e8b053 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 6 Apr 2005 10:27:40 +0300 Subject: [PATCH 42/83] row0sel.c, btr0pcur.c, btr0pcur.ic, btr0pcur.h: Add diagnostic code to track assertion failure in ut_a(cursor->old_stored == BTR_PCUR_OLD_STORED); the failure happened in OPTIMIZE TABLE, and in 4.0.24 in some other context --- innobase/btr/btr0pcur.c | 10 +++++++++- innobase/include/btr0pcur.h | 4 ++++ innobase/include/btr0pcur.ic | 10 ++++++++++ innobase/row/row0sel.c | 4 ++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/innobase/btr/btr0pcur.c b/innobase/btr/btr0pcur.c index cf8a612ef28..0dcf6c2f3fc 100644 --- a/innobase/btr/btr0pcur.c +++ b/innobase/btr/btr0pcur.c @@ -14,6 +14,7 @@ Created 2/23/1996 Heikki Tuuri #include "ut0byte.h" #include "rem0cmp.h" +#include "trx0trx.h" /****************************************************************** Allocates memory for a persistent cursor object and initializes the cursor. */ @@ -203,7 +204,14 @@ btr_pcur_restore_position( ut_a(cursor->pos_state == BTR_PCUR_WAS_POSITIONED || cursor->pos_state == BTR_PCUR_IS_POSITIONED); - ut_a(cursor->old_stored == BTR_PCUR_OLD_STORED); + if (cursor->old_stored != BTR_PCUR_OLD_STORED) { + ut_print_buf(stderr, (const byte*)cursor, sizeof(btr_pcur_t)); + if (cursor->trx_if_known) { + trx_print(stderr, cursor->trx_if_known); + } + + ut_a(0); + } if (cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) { diff --git a/innobase/include/btr0pcur.h b/innobase/include/btr0pcur.h index 81f19af4d40..9339eb5d0ee 100644 --- a/innobase/include/btr0pcur.h +++ b/innobase/include/btr0pcur.h @@ -477,6 +477,10 @@ struct btr_pcur_struct{ BTR_PCUR_WAS_POSITIONED, BTR_PCUR_NOT_POSITIONED */ ulint search_mode; /* PAGE_CUR_G, ... */ + trx_t* trx_if_known; /* the transaction, if we know it; + otherwise this field is not defined; + can ONLY BE USED in error prints in + fatal assertion failures! */ /*-----------------------------*/ /* NOTE that the following fields may possess dynamically allocated memory which should be freed if not needed anymore! */ diff --git a/innobase/include/btr0pcur.ic b/innobase/include/btr0pcur.ic index b553a569bda..9a7d7867025 100644 --- a/innobase/include/btr0pcur.ic +++ b/innobase/include/btr0pcur.ic @@ -493,6 +493,8 @@ btr_pcur_open( btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode, btr_cursor, 0, mtr); cursor->pos_state = BTR_PCUR_IS_POSITIONED; + + cursor->trx_if_known = NULL; } /****************************************************************** @@ -535,6 +537,8 @@ btr_pcur_open_with_no_init( cursor->pos_state = BTR_PCUR_IS_POSITIONED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; + + cursor->trx_if_known = NULL; } /********************************************************************* @@ -568,6 +572,8 @@ btr_pcur_open_at_index_side( pcur->pos_state = BTR_PCUR_IS_POSITIONED; pcur->old_stored = BTR_PCUR_OLD_NOT_STORED; + + pcur->trx_if_known = NULL; } /************************************************************************** @@ -592,6 +598,8 @@ btr_pcur_open_at_rnd_pos( btr_pcur_get_btr_cur(cursor), mtr); cursor->pos_state = BTR_PCUR_IS_POSITIONED; cursor->old_stored = BTR_PCUR_OLD_NOT_STORED; + + cursor->trx_if_known = NULL; } /****************************************************************** @@ -617,4 +625,6 @@ btr_pcur_close( cursor->latch_mode = BTR_NO_LATCHES; cursor->pos_state = BTR_PCUR_NOT_POSITIONED; + + cursor->trx_if_known = NULL; } diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 07140e74e54..eb88ac31ba9 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2507,6 +2507,8 @@ row_sel_get_clust_rec_for_mysql( clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur); + prebuilt->clust_pcur->trx_if_known = trx; + /* Note: only if the search ends up on a non-infimum record is the low_match value the real match to the search tuple */ @@ -3222,6 +3224,8 @@ shortcut_fails_too_big_rec: btr_pcur_open_with_no_init(index, search_tuple, mode, BTR_SEARCH_LEAF, pcur, 0, &mtr); + + pcur->trx_if_known = trx; } else { if (mode == PAGE_CUR_G) { btr_pcur_open_at_index_side(TRUE, index, From 6f18d7d26f0a8348dd6599f2994dd20ddf19679c Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Wed, 6 Apr 2005 14:13:06 +0500 Subject: [PATCH 43/83] Fix for bug #9286: SESSION/GLOBAL should be disallowed for user variables --- BitKeeper/etc/logging_ok | 1 + mysql-test/r/user_var.result | 4 +++ mysql-test/t/user_var.test | 8 +++++ sql/sql_yacc.yy | 66 +++++++++++++++++++++--------------- 4 files changed, 52 insertions(+), 27 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 90e6c3c100d..9237eea21c4 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -51,6 +51,7 @@ georg@lmy002.wdf.sap.corp gerberb@ou800.zenez.com gluh@gluh.(none) gluh@gluh.mysql.r18.ru +gluh@mysql.com gordon@zero.local.lan greg@gcw.ath.cx greg@mysql.com diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 9edeea404ec..e42849abdf1 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -175,3 +175,7 @@ set @v1=null, @v2=1, @v3=1.1, @v4=now(); select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4); coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4) 2 2 2 2 +set session @honk=99; +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 '@honk=99' at line 1 +set one_shot @honk=99; +ERROR HY000: The SET ONE_SHOT syntax is reserved for purposes internal to the MySQL server diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index b907f21056c..a288b7ef708 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -111,3 +111,11 @@ select FIELD( @var,'1it','Hit') as my_column; select @v, coercibility(@v); set @v1=null, @v2=1, @v3=1.1, @v4=now(); select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4); + +# +# Bug #9286 SESSION/GLOBAL should be disallowed for user variables +# +--error 1064 +set session @honk=99; +--error 1105 +set one_shot @honk=99; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9f25e17b6fd..4a23a393fa9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5360,17 +5360,26 @@ opt_option: | OPTION {}; option_value_list: - option_type option_value - | option_value_list ',' option_type option_value; + option_value_ext + | option_value_list ',' option_value_ext; -option_type: - /* empty */ {} +option_value_ext: + option_type_ext sys_option_value {} + | option_type option_value {} + ; + +option_type_ext: + option_type {} | GLOBAL_SYM { Lex->option_type= OPT_GLOBAL; } | LOCAL_SYM { Lex->option_type= OPT_SESSION; } | SESSION_SYM { Lex->option_type= OPT_SESSION; } - | ONE_SHOT_SYM { Lex->option_type= OPT_SESSION; Lex->one_shot_set= 1; } ; +option_type: + /* empty */ {} + | ONE_SHOT_SYM { Lex->option_type= OPT_SESSION; Lex->one_shot_set= 1; } + ; + opt_var_type: /* empty */ { $$=OPT_SESSION; } | GLOBAL_SYM { $$=OPT_GLOBAL; } @@ -5385,34 +5394,37 @@ opt_var_ident_type: | SESSION_SYM '.' { $$=OPT_SESSION; } ; +sys_option_value: + internal_variable_name equal set_expr_or_default + { + LEX *lex=Lex; + lex->var_list.push_back(new set_var(lex->option_type, $1.var, + &$1.base_name, $3)); + } + | TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types + { + LEX *lex=Lex; + LEX_STRING tmp; + tmp.str=0; + tmp.length=0; + lex->var_list.push_back(new set_var(lex->option_type, + find_sys_var("tx_isolation"), + &tmp, + new Item_int((int32) $4))); + } + ; + option_value: '@' ident_or_text equal expr { Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4))); } - | internal_variable_name equal set_expr_or_default - { - LEX *lex=Lex; - lex->var_list.push_back(new set_var(lex->option_type, $1.var, - &$1.base_name, $3)); - } | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default - { - LEX *lex=Lex; - lex->var_list.push_back(new set_var((enum_var_type) $3, $4.var, - &$4.base_name, $6)); - } - | TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types - { - LEX *lex=Lex; - LEX_STRING tmp; - tmp.str=0; - tmp.length=0; - lex->var_list.push_back(new set_var(lex->option_type, - find_sys_var("tx_isolation"), - &tmp, - new Item_int((int32) $4))); - } + { + LEX *lex=Lex; + lex->var_list.push_back(new set_var((enum_var_type) $3, $4.var, + &$4.base_name, $6)); + } | charset old_or_new_charset_name_or_default { THD *thd= YYTHD; From 1c46a020695b3720cf8ce2fd86b566447fdedccc Mon Sep 17 00:00:00 2001 From: "bar@mysql.com" <> Date: Wed, 6 Apr 2005 15:12:44 +0500 Subject: [PATCH 44/83] Minor clean-ups for the previous commit. --- sql/field.cc | 8 ++++---- strings/ctype-mb.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index 740c027350d..d73257a673f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4914,7 +4914,7 @@ void Field_datetime::sql_type(String &res) const int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) { - int error= 0; + int error= 0, well_formed_error; uint32 not_used; char buff[80]; String tmpstr(buff,sizeof(buff), &my_charset_bin); @@ -4942,7 +4942,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) from,from+length, field_length/ field_charset->mbmaxlen, - &error); + &well_formed_error); memcpy(ptr,from,copy_length); if (copy_length < field_length) // Append spaces if shorter field_charset->cset->fill(field_charset,ptr+copy_length, @@ -5545,7 +5545,7 @@ void Field_blob::put_length(char *pos, uint32 length) int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) { - int error= 0; + int error= 0, well_formed_error; if (!length) { bzero(ptr,Field_blob::pack_length()); @@ -5580,7 +5580,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) from,from + min(length, copy_length), copy_length, - &error); + &well_formed_error); if (copy_length < length) error= 1; Field_blob::store_length(copy_length); diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index dbe3a24324e..cbbd035c631 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -276,7 +276,7 @@ uint my_well_formed_len_mb(CHARSET_INFO *cs, const char *b, const char *e, if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0) { - *error= 1; + *error= b < e ? 1 : 0; break; } b+= mblen; From 57d89142878202551462bdae7259d77e629b37ba Mon Sep 17 00:00:00 2001 From: "kent@mysql.com" <> Date: Wed, 6 Apr 2005 12:20:55 +0200 Subject: [PATCH 45/83] Makefile.am: Include the Perl version of mysql-test-run rpl_rewrite_db.test, rpl_rewrite_db.result: Added missing database cleanup mysql-test-run.pl: Embedded result files no longer needed --- mysql-test/Makefile.am | 15 ++++++++++----- mysql-test/mysql-test-run.pl | 1 - mysql-test/r/rpl_rewrite_db.result | 1 + mysql-test/t/rpl_rewrite_db.test | 3 +++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index b2e86d8c00e..57598f5f3e3 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -32,21 +32,21 @@ endif benchdir_root= $(prefix) testdir = $(benchdir_root)/mysql-test -EXTRA_SCRIPTS = mysql-test-run.sh install_test_db.sh +EXTRA_SCRIPTS = mysql-test-run.sh mysql-test-run.pl install_test_db.sh EXTRA_DIST = $(EXTRA_SCRIPTS) test_SCRIPTS = mysql-test-run install_test_db test_DATA = std_data/client-key.pem std_data/client-cert.pem std_data/cacert.pem CLEANFILES = $(test_SCRIPTS) $(test_DATA) -INCLUDES = -I$(srcdir)/../include -I../include -I.. -EXTRA_PROGRAMS = mysql_test_run_new +INCLUDES = -I$(srcdir)/../include -I../include -I.. +EXTRA_PROGRAMS = mysql_test_run_new noinst_HEADERS = my_manage.h mysql_test_run_new_SOURCES= mysql_test_run_new.c my_manage.c my_create_tables.c dist-hook: mkdir -p $(distdir)/t $(distdir)/r $(distdir)/include \ - $(distdir)/std_data + $(distdir)/std_data $(distdir)/lib $(INSTALL_DATA) $(srcdir)/t/*.test $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t $(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.result.es $(srcdir)/r/*.require $(distdir)/r @@ -54,6 +54,8 @@ dist-hook: $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.000001 $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.pem $(distdir)/std_data + $(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(distdir)/lib + $(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib install-data-local: @@ -61,7 +63,8 @@ install-data-local: $(DESTDIR)$(testdir)/t \ $(DESTDIR)$(testdir)/r \ $(DESTDIR)$(testdir)/include \ - $(DESTDIR)$(testdir)/std_data + $(DESTDIR)$(testdir)/std_data \ + $(DESTDIR)$(testdir)/lib $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(testdir) $(INSTALL_DATA) $(srcdir)/t/*.test $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.opt $(DESTDIR)$(testdir)/t @@ -75,6 +78,8 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data + $(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(DESTDIR)$(testdir)/lib + $(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib std_data/%.pem: @CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ae5caa8044a..e4f14447e30 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -635,7 +635,6 @@ sub command_line_setup () { { mtr_error("Can't use --extern with --embedded-server"); } - $opt_result_ext= ".es"; } # FIXME don't understand what this is diff --git a/mysql-test/r/rpl_rewrite_db.result b/mysql-test/r/rpl_rewrite_db.result index a2c8706e3e1..da3ec0243fe 100644 --- a/mysql-test/r/rpl_rewrite_db.result +++ b/mysql-test/r/rpl_rewrite_db.result @@ -89,4 +89,5 @@ a b 2 row 2 3 row 3 0 +drop database rewrite; drop table t1; diff --git a/mysql-test/t/rpl_rewrite_db.test b/mysql-test/t/rpl_rewrite_db.test index b6118854037..b77d57294fa 100644 --- a/mysql-test/t/rpl_rewrite_db.test +++ b/mysql-test/t/rpl_rewrite_db.test @@ -73,5 +73,8 @@ connection slave; # The empty line last comes from the end line field in the file select * from rewrite.t1; +drop database rewrite; + connection master; drop table t1; + From 1e030d5d9349100d91019b056a91c51ba8745768 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Wed, 6 Apr 2005 12:27:43 +0200 Subject: [PATCH 46/83] BUG#9626 Several serious errors reported by Valgrind in latest 5.0 bk tree - Fixing obvious ones --- sql/ha_ndbcluster.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index e3f6235c62c..0668c3db7a8 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -5803,6 +5803,7 @@ extern "C" pthread_handler_decl(ndb_util_thread_func, { thd->cleanup(); delete thd; + delete ndb; DBUG_RETURN(NULL); } @@ -5921,6 +5922,7 @@ extern "C" pthread_handler_decl(ndb_util_thread_func, thd->cleanup(); delete thd; + delete ndb; DBUG_PRINT("exit", ("ndb_util_thread")); my_thread_end(); pthread_exit(0); From 7cd0e4343758e7440e6f77329abaddd6fd52b398 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Wed, 6 Apr 2005 15:49:55 +0500 Subject: [PATCH 47/83] Stupid error message for 'insert "aaa"' into decimal column fixed --- mysql-test/r/row.result | 2 +- sql/item.cc | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result index 40a31563604..9734efb0797 100644 --- a/mysql-test/r/row.result +++ b/mysql-test/r/row.result @@ -15,7 +15,7 @@ select row('a',1.5,3) IN (row(1,2,3), row('a',1.5,3), row('a','a','a')); row('a',1.5,3) IN (row(1,2,3), row('a',1.5,3), row('a','a','a')) 1 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: 'a' select row('a',0,3) IN (row(3,2,3), row('a','0','3'), row(1,3,3)); row('a',0,3) IN (row(3,2,3), row('a','0','3'), row(1,3,3)) 1 diff --git a/sql/item.cc b/sql/item.cc index 48faa3509f4..b7d9f177c53 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -260,8 +260,15 @@ my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value) return 0; // NULL or EOM end_ptr= (char*) res->ptr()+ res->length(); - str2my_decimal(E_DEC_FATAL_ERROR, res->ptr(), res->length(), res->charset(), - decimal_value); + if (str2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_BAD_NUM, + res->ptr(), res->length(), res->charset(), + decimal_value) & E_DEC_BAD_NUM) + { + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TRUNCATED_WRONG_VALUE, + ER(ER_TRUNCATED_WRONG_VALUE), "DECIMAL", + str_value.c_ptr()); + } return decimal_value; } @@ -1457,10 +1464,7 @@ void Item_string::print(String *str) my_decimal *Item_string::val_decimal(my_decimal *decimal_value) { - /* following assert is redundant, because fixed=1 assigned in constructor */ - DBUG_ASSERT(fixed == 1); - string2my_decimal(E_DEC_FATAL_ERROR, &str_value, decimal_value); - return (decimal_value); + return val_decimal_from_string(decimal_value); } From f32fe9c154adbd169407c0bf3c11647dc7f0f7b8 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Wed, 6 Apr 2005 15:09:15 +0300 Subject: [PATCH 48/83] InnoDB: Avoid test suite failures caused by a locking conflict between two server instances at server shutdown/startup. This conflict on advisory locks appears to be the result of a bug in the operating system; these locks should be released when the files are closed, but somehow that does not always happen immediately in Linux. (Bug #9381) --- innobase/include/os0file.h | 2 ++ innobase/os/os0file.c | 27 +++++++++++++++++++++++---- innobase/srv/srv0start.c | 5 +++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index d1439faf29f..ebc014df9fd 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -65,6 +65,8 @@ log. */ #define OS_FILE_OVERWRITE 53 #define OS_FILE_OPEN_RAW 54 #define OS_FILE_CREATE_PATH 55 +#define OS_FILE_OPEN_RETRY 56 /* for os_file_create() on + the first ibdata file */ #define OS_FILE_READ_ONLY 333 #define OS_FILE_READ_WRITE 444 diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 8d1ad895aa9..15f5bf40e51 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -402,8 +402,6 @@ os_file_lock( "InnoDB: using the same InnoDB data or log files.\n"); } - close(fd); - return(-1); } @@ -978,6 +976,7 @@ try_again: } else if (access_type == OS_FILE_READ_WRITE && os_file_lock(file, name)) { *success = FALSE; + close(file); file = -1; #endif } else { @@ -1090,6 +1089,7 @@ os_file_create_simple_no_error_handling( } else if (access_type == OS_FILE_READ_WRITE && os_file_lock(file, name)) { *success = FALSE; + close(file); file = -1; #endif } else { @@ -1141,7 +1141,8 @@ try_again: if (create_mode == OS_FILE_OPEN_RAW) { create_flag = OPEN_EXISTING; share_mode = FILE_SHARE_WRITE; - } else if (create_mode == OS_FILE_OPEN) { + } else if (create_mode == OS_FILE_OPEN + || create_mode == OS_FILE_OPEN_RETRY) { create_flag = OPEN_EXISTING; } else if (create_mode == OS_FILE_CREATE) { create_flag = CREATE_NEW; @@ -1232,7 +1233,8 @@ try_again: try_again: ut_a(name); - if (create_mode == OS_FILE_OPEN || create_mode == OS_FILE_OPEN_RAW) { + if (create_mode == OS_FILE_OPEN || create_mode == OS_FILE_OPEN_RAW + || create_mode == OS_FILE_OPEN_RETRY) { mode_str = "OPEN"; create_flag = O_RDWR; } else if (create_mode == OS_FILE_CREATE) { @@ -1305,6 +1307,23 @@ try_again: } else if (create_mode != OS_FILE_OPEN_RAW && os_file_lock(file, name)) { *success = FALSE; + if (create_mode == OS_FILE_OPEN_RETRY) { + int i; + ut_print_timestamp(stderr); + fputs(" InnoDB: Retrying to lock the first data file\n", + stderr); + for (i = 0; i < 100; i++) { + os_thread_sleep(1000000); + if (!os_file_lock(file, name)) { + *success = TRUE; + return(file); + } + } + ut_print_timestamp(stderr); + fputs(" InnoDB: Unable to open the first data file\n", + stderr); + } + close(file); file = -1; #endif } else { diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 44cf645f170..62df7301cc9 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -789,6 +789,11 @@ open_or_create_data_files( files[i] = os_file_create( name, OS_FILE_OPEN_RAW, OS_FILE_NORMAL, OS_DATA_FILE, &ret); + } else if (i == 0) { + files[i] = os_file_create( + name, OS_FILE_OPEN_RETRY, + OS_FILE_NORMAL, + OS_DATA_FILE, &ret); } else { files[i] = os_file_create( name, OS_FILE_OPEN, OS_FILE_NORMAL, From 49e721677f9eec2ae8e869dacc8acb522f72ef05 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Wed, 6 Apr 2005 17:22:21 +0300 Subject: [PATCH 49/83] Fixed errors descovered by valgrind 2.4 Added suppression file for some valgrind warnings that are not real errors --- mysql-test/mysql-test-run.sh | 2 +- mysql-test/r/heap.result | 21 ++----- mysql-test/t/heap.test | 27 +++------ mysql-test/valgrind.supp | 94 +++++++++++++++++++++++++++++ mysys/default.c | 4 +- scripts/make_binary_distribution.sh | 1 + sql/ha_federated.cc | 6 +- sql/ha_heap.cc | 1 + sql/mysqld.cc | 3 +- sql/sql_parse.cc | 3 +- strings/decimal.c | 2 +- 11 files changed, 121 insertions(+), 43 deletions(-) create mode 100644 mysql-test/valgrind.supp diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index ac1755cab9c..d294ef50421 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -418,7 +418,7 @@ while test $# -gt 0; do fi # >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck" - VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16" + VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16 --suppressions=$CWD/valgrind.supp" EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb" EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb" SLEEP_TIME_AFTER_RESTART=10 diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index db20b242962..631bd8c713c 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -667,14 +667,7 @@ drop table t1; set storage_engine=MyISAM; create table t1 (a bigint unsigned auto_increment primary key, b int, key (b, a)) engine=heap; -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); +insert t1 (b) values (1),(1),(1),(1),(1),(1),(1),(1); select * from t1; a b 1 1 @@ -688,14 +681,7 @@ a b drop table t1; create table t1 (a int not null, b int not null auto_increment, primary key(a, b), key(b)) engine=heap; -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); +insert t1 (a) values (1),(1),(1),(1),(1),(1),(1),(1); select * from t1; a b 1 1 @@ -707,3 +693,6 @@ a b 1 7 1 8 drop table t1; +create table t1 (a int not null, b int not null auto_increment, +primary key(a, b)) engine=heap; +ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test index b69649585ff..c36474bda30 100644 --- a/mysql-test/t/heap.test +++ b/mysql-test/t/heap.test @@ -413,25 +413,16 @@ eval set storage_engine=$default; create table t1 (a bigint unsigned auto_increment primary key, b int, key (b, a)) engine=heap; -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -insert t1 (b) values (1); -select * from t1; +insert t1 (b) values (1),(1),(1),(1),(1),(1),(1),(1); +select * from t1; drop table t1; + create table t1 (a int not null, b int not null auto_increment, primary key(a, b), key(b)) engine=heap; -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -insert t1 (a) values (1); -select * from t1; +insert t1 (a) values (1),(1),(1),(1),(1),(1),(1),(1); +select * from t1; drop table t1; + +--error 1075 +create table t1 (a int not null, b int not null auto_increment, + primary key(a, b)) engine=heap; diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp new file mode 100644 index 00000000000..d8a13ca9dfd --- /dev/null +++ b/mysql-test/valgrind.supp @@ -0,0 +1,94 @@ +# +# Suppress some common (not fatal) errors in system libraries found by valgrind +# + +# +# Pthread doesn't free all thread specific memory before program exists +# +{ + pthread allocate_tls memory loss + Memcheck:Leak + fun:calloc + fun:_dl_allocate_tls + fun:allocate_stack + fun:pthread_create@@GLIBC_2.1 +} + +{ + pthread allocate_dtv memory loss + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls_storage + fun:__GI__dl_allocate_tls + fun:pthread_create +} + +{ + pthread memalign memory loss + Memcheck:Leak + fun:memalign + fun:_dl_allocate_tls_storage + fun:__GI__dl_allocate_tls + fun:pthread_create +} + +{ + pthread errno + Memcheck:Leak + fun:calloc + fun:_dlerror_run + fun:dlsym + fun:__errno_location +} + + +# +# Warnings in libz becasue it works with aligned memory(?) +# + +{ + libz tr_flush_block + Memcheck:Cond + fun:_tr_flush_block + fun:deflate_slow + fun:deflate + fun:do_flush + fun:gzclose +} + +{ + libz tr_flush_block2 + Memcheck:Cond + fun:_tr_flush_block + fun:deflate_slow + fun:deflate + fun:compress2 +} + +{ + libz longest_match + Memcheck:Cond + fun:longest_match + fun:deflate_slow + fun:deflate + fun:do_flush +} + +{ + libz longest_match2 + Memcheck:Cond + fun:longest_match + fun:deflate_slow + fun:deflate + fun:compress2 +} + +{ + libz deflate + Memcheck:Cond + obj:/usr/lib/libz.so.* + obj:/usr/lib/libz.so.* + fun:deflate + fun:compress2 +} diff --git a/mysys/default.c b/mysys/default.c index ddff4e26be5..6352cc18d56 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -477,13 +477,13 @@ static int search_default_file_with_ext(Process_option_func opt_handler, if ((stat_info.st_mode & S_IWOTH) && (stat_info.st_mode & S_IFMT) == S_IFREG) { - fprintf(stderr, "warning: World-writable config file %s is ignored\n", + fprintf(stderr, "Warning: World-writable config file '%s' is ignored\n", name); return 0; } } #endif - if (!(fp= my_fopen(fn_format(name, name, "", "", 4), O_RDONLY, MYF(0)))) + if (!(fp= my_fopen(name, O_RDONLY, MYF(0)))) return 0; /* Ignore wrong files */ while (fgets(buff, sizeof(buff) - 1, fp)) diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index ddce55c063d..22bf13d8bef 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -207,6 +207,7 @@ rm -f $MYSQL_SHARE/Makefile* $MYSQL_SHARE/*/*.OLD for i in mysql-test/mysql-test-run mysql-test/install_test_db \ mysql-test/mysql-test-run.pl mysql-test/README \ + mysql-test/valgrind.supp \ netware/mysql_test_run.nlm netware/install_test_db.ncf do if [ -f $i ] diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 8000aae180d..33acc9cad0b 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -548,12 +548,12 @@ error: static int parse_url(FEDERATED_SHARE *share, TABLE *table, uint table_create_flag) { + uint error_num= (table_create_flag ? ER_CANT_CREATE_TABLE : + ER_CONNECT_TO_MASTER); DBUG_ENTER("ha_federated::parse_url"); share->port= 0; - uint error_num= (table_create_flag ? ER_CANT_CREATE_TABLE : - ER_CONNECT_TO_MASTER); - + share->socket= 0; share->scheme= my_strdup(table->s->comment, MYF(0)); if ((share->username= strstr(share->scheme, "://"))) diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index de51fad4365..0d700f6c9a5 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -548,6 +548,7 @@ int ha_heap::create(const char *name, TABLE *table_arg, hp_create_info.auto_increment= (create_info->auto_increment_value ? create_info->auto_increment_value - 1 : 0); hp_create_info.max_table_size=current_thd->variables.max_heap_table_size; + hp_create_info.with_auto_increment= found_real_auto_increment; max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row); error= heap_create(fn_format(buff,name,"","",4+2), keys, keydef, share->reclength, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e1303585114..7611270fc42 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1519,6 +1519,7 @@ void end_thread(THD *thd, bool put_in_cache) thd=thread_cache.get(); thd->real_id=pthread_self(); (void) thd->store_globals(); + thd->thr_create_time= time(NULL); threads.append(thd); pthread_mutex_unlock(&LOCK_thread_count); DBUG_VOID_RETURN; @@ -5180,7 +5181,7 @@ log and this option does nothing anymore.", (gptr*) &dflt_key_cache_var.param_buff_size, (gptr*) 0, 0, (GET_ULL | GET_ASK_ADDR), - REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, UINT_MAX32, MALLOC_OVERHEAD, + REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, ~(ulong) 0, MALLOC_OVERHEAD, IO_SIZE, 0}, {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD, "This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache", diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1d7eba4ce43..9e7cf81de3c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1103,7 +1103,8 @@ pthread_handler_decl(handle_one_connection,arg) thd->proc_info=0; thd->set_time(); thd->init_for_queries(); - while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION)) + while (!net->error && net->vio != 0 && + !(thd->killed == THD::KILL_CONNECTION)) { net->no_send_error= 0; if (do_command(thd)) diff --git a/strings/decimal.c b/strings/decimal.c index 56dba61d887..9af95511f6d 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -806,7 +806,7 @@ internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed) if (s < end_of_string && *s=='.') { endp= s+1; - while (s < end_of_string && my_isdigit(&my_charset_latin1, *endp)) + while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp)) endp++; frac= endp - s - 1; } From a7c6348192b857e12d8219bed24e44fee15ae181 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Wed, 6 Apr 2005 19:43:35 +0300 Subject: [PATCH 50/83] Fixed errors found during review --- mysql-test/r/drop.result | 4 ++-- mysql-test/r/kill.result | 2 +- mysql-test/t/kill.test | 2 +- mysys/my_sync.c | 2 +- sql/records.cc | 2 +- sql/share/errmsg.txt | 48 ++++++++++++++++++++-------------------- sql/sql_class.cc | 5 +++-- sql/sql_show.cc | 2 +- 8 files changed, 34 insertions(+), 33 deletions(-) diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index b91cc89cfea..979e5d48871 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -30,13 +30,13 @@ table7, table8, table9, table10, table11, table12, table13, table14, table15, table16, table17, table18, table19, table20, table21, table22, table23, table24, table25, table26, table27, table28; -ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table14,table15,table16,table17,table18,table19,table20,table21,table22,table23,table' +ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table' drop table table1, table2, table3, table4, table5, table6, table7, table8, table9, table10, table11, table12, table13, table14, table15, table16, table17, table18, table19, table20, table21, table22, table23, table24, table25, table26, table27, table28, table29, table30; -ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table14,table15,table16,table17,table18,table19,table20,table21,table22,table23,table' +ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table' use test; drop database mysqltest; flush tables with read lock; diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index 049281ad5d4..754568093ff 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -6,7 +6,7 @@ select ((@id := kill_id) - kill_id) from t1; 0 kill @id; select 1; -ERROR HY000: MySQL server has gone away +Got one of the listed errors select ((@id := kill_id) - kill_id) from t1; ((@id := kill_id) - kill_id) 0 diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index 6744a212828..37e11e14df5 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -27,7 +27,7 @@ connection con1; --disable_reconnect # this statement should fail ---error 2006 +--error 2006,2013 select 1; --enable_reconnect # this should work, and we should have a new connection_id() diff --git a/mysys/my_sync.c b/mysys/my_sync.c index bfaf09ce402..c557324b52c 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -65,7 +65,7 @@ int my_sync(File fd, myf my_flags) int er= errno; if (!(my_errno= er)) my_errno= -1; /* Unknown error */ - if (my_flags & MY_IGNORE_BADFD && + if ((my_flags & MY_IGNORE_BADFD) && (er == EBADF || er == EINVAL || er == EROFS)) res= 0; else if (my_flags & MY_WME) diff --git a/sql/records.cc b/sql/records.cc index cfb7cb3d065..b71bcf70865 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -131,7 +131,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, /* Condition pushdown to storage engine */ if (thd->variables.engine_condition_pushdown && select && select->cond && - select->cond->used_tables() & table->map && + (select->cond->used_tables() & table->map) && !table->file->pushed_cond) table->file->cond_push(select->cond); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 9a92f1f4f76..46c8fcc7863 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -1214,30 +1214,30 @@ ER_TABLE_EXISTS_ERROR 42S01 swe "Tabellen '%-.64s' finns redan" ukr " '%-.64s' դ" ER_BAD_TABLE_ERROR 42S02 - cze "Nezn-Bm tabulka '%-.180s'" - dan "Ukendt tabel '%-.180s'" - nla "Onbekende tabel '%-.180s'" - eng "Unknown table '%-.180s'" - jps "table '%-.180s' ͂܂.", - est "Tundmatu tabel '%-.180s'" - fre "Table '%-.180s' inconnue" - ger "Unbekannte Tabelle '%-.180s'" - greek " '%-.180s'" - hun "Ervenytelen tabla: '%-.180s'" - ita "Tabella '%-.180s' sconosciuta" - jpn "table '%-.180s' Ϥޤ." - kor "̺ '%-.180s' ˼ " - nor "Ukjent tabell '%-.180s'" - norwegian-ny "Ukjent tabell '%-.180s'" - pol "Nieznana tabela '%-.180s'" - por "Tabela '%-.180s' desconhecida" - rum "Tabela '%-.180s' este invalida" - rus " '%-.180s'" - serbian "Nepoznata tabela '%-.180s'" - slo "Neznma tabuka '%-.180s'" - spa "Tabla '%-.180s' desconocida" - swe "Oknd tabell '%-.180s'" - ukr "צ '%-.180s'" + cze "Nezn-Bm tabulka '%-.100s'" + dan "Ukendt tabel '%-.100s'" + nla "Onbekende tabel '%-.100s'" + eng "Unknown table '%-.100s'" + jps "table '%-.100s' ͂܂.", + est "Tundmatu tabel '%-.100s'" + fre "Table '%-.100s' inconnue" + ger "Unbekannte Tabelle '%-.100s'" + greek " '%-.100s'" + hun "Ervenytelen tabla: '%-.100s'" + ita "Tabella '%-.100s' sconosciuta" + jpn "table '%-.100s' Ϥޤ." + kor "̺ '%-.100s' ˼ " + nor "Ukjent tabell '%-.100s'" + norwegian-ny "Ukjent tabell '%-.100s'" + pol "Nieznana tabela '%-.100s'" + por "Tabela '%-.100s' desconhecida" + rum "Tabela '%-.100s' este invalida" + rus " '%-.100s'" + serbian "Nepoznata tabela '%-.100s'" + slo "Neznma tabuka '%-.100s'" + spa "Tabla '%-.100s' desconocida" + swe "Oknd tabell '%-.100s'" + ukr "צ '%-.100s'" ER_NON_UNIQ_ERROR 23000 cze "Sloupec '%-.64s' v %s nen-B zcela jasn" dan "Felt: '%-.64s' i tabel %s er ikke entydigt" diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cdda013d23a..c68dc826147 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -343,8 +343,9 @@ void THD::change_user(void) void THD::cleanup(void) { DBUG_ENTER("THD::cleanup"); - /* TODO uncomment the line below when binlog will be able to prepare */ - // if (transaction.xa_state != XA_PREPARED) +#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE + if (transaction.xa_state != XA_PREPARED) +#endif ha_rollback(this); if (locked_tables) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d2cab6bf49f..8b906f133ba 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2312,7 +2312,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, } } #else - end=strmov(end,""); + *end= 0; #endif table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs); From 70aecbb8a450fedc3390e71daf7bd432db376b04 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Wed, 6 Apr 2005 21:48:16 +0400 Subject: [PATCH 51/83] Refactor parts of do_select() (JOIN execution). --- sql/sql_select.cc | 93 +++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 410b3090b5c..cbde0752cd1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -111,6 +111,7 @@ static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item); static bool open_tmp_table(TABLE *table); static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, ulong options); +static Next_select_func setup_end_select_func(JOIN *join); static int do_select(JOIN *join,List *fields,TABLE *tmp_table, Procedure *proc); static int sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records); @@ -1638,6 +1639,8 @@ JOIN::exec() { thd->proc_info="Sending data"; DBUG_PRINT("info", ("%s", thd->proc_info)); + result->send_fields(*curr_fields_list, + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); error= do_select(curr_join, curr_fields_list, NULL, procedure); thd->limit_found_rows= curr_join->send_records; thd->examined_row_count= curr_join->examined_rows; @@ -1776,12 +1779,7 @@ Cursor::open(JOIN *join_arg) thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS; /* Prepare JOIN for reading rows. */ - - Next_select_func end_select= join->sort_and_group || join->procedure && - join->procedure->flags & PROC_GROUP ? - end_send_group : end_send; - - join->join_tab[join->tables-1].next_select= end_select; + join->join_tab[join->tables-1].next_select= setup_end_select_func(join); join->send_records= 0; join->fetch_limit= join->unit->offset_limit_cnt; @@ -1802,6 +1800,11 @@ Cursor::open(JOIN *join_arg) */ DBUG_ASSERT(join_tab->table->null_row == 0); + /* + There is always at least one record in the table, as otherwise we + wouldn't have opened the cursor. Therefore a failure is the only + reason read_first_record can return not 0. + */ DBUG_RETURN(join_tab->read_first_record(join_tab)); } @@ -8733,36 +8736,24 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, } -/**************************************************************************** - Make a join of all tables and write it on socket or to table - Return: 0 if ok - 1 if error is sent - -1 if error should be sent -****************************************************************************/ +/* + SYNOPSIS + setup_end_select_func() + join join to setup the function for. -static int -do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) + DESCRIPTION + Rows produced by a join sweep may end up in a temporary table or be sent + to a client. Setup the function of the nested loop join algorithm which + handles final fully constructed and matched records. + + RETURN + end_select function to use. This function can't fail. +*/ + +static Next_select_func setup_end_select_func(JOIN *join) { - int error= 0; - JOIN_TAB *join_tab; + TABLE *table= join->tmp_table; Next_select_func end_select; - DBUG_ENTER("do_select"); - - join->procedure=procedure; - /* - Tell the client how many fields there are in a row - */ - if (!table) - join->result->send_fields(*fields, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); - else - { - VOID(table->file->extra(HA_EXTRA_WRITE_CACHE)); - empty_record(table); - } - join->tmp_table= table; /* Save for easy recursion */ - join->fields= fields; - /* Set up select_end */ if (table) { @@ -8772,8 +8763,6 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) { DBUG_PRINT("info",("Using end_update")); end_select=end_update; - if (!table->file->inited) - table->file->ha_index_init(0); } else { @@ -8807,7 +8796,38 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) else end_select= end_send; } - join->join_tab[join->tables-1].next_select=end_select; + return end_select; +} + + +/**************************************************************************** + Make a join of all tables and write it on socket or to table + Return: 0 if ok + 1 if error is sent + -1 if error should be sent +****************************************************************************/ + +static int +do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) +{ + int error= 0; + JOIN_TAB *join_tab; + DBUG_ENTER("do_select"); + + join->procedure=procedure; + join->tmp_table= table; /* Save for easy recursion */ + join->fields= fields; + + if (table) + { + VOID(table->file->extra(HA_EXTRA_WRITE_CACHE)); + empty_record(table); + if (table->group && join->tmp_table_param.sum_func_count && + table->s->keys && !table->file->inited) + table->file->ha_index_init(0); + } + /* Set up select_end */ + join->join_tab[join->tables-1].next_select= setup_end_select_func(join); join_tab=join->join_tab+join->const_tables; join->send_records=0; @@ -8819,6 +8839,7 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) */ if (!join->conds || join->conds->val_int()) { + Next_select_func end_select= join->join_tab[join->tables-1].next_select; if (!(error=(*end_select)(join,join_tab,0)) || error == -3) error=(*end_select)(join,join_tab,1); } From 5f8d71710b6e8a8a147e00feff86bff140ec7696 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Wed, 6 Apr 2005 22:09:43 +0400 Subject: [PATCH 52/83] Minor fix in cursors execution. --- sql/sql_select.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index cbde0752cd1..baf2ef09d2b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1779,6 +1779,7 @@ Cursor::open(JOIN *join_arg) thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS; /* Prepare JOIN for reading rows. */ + join->tmp_table= 0; join->join_tab[join->tables-1].next_select= setup_end_select_func(join); join->send_records= 0; join->fetch_limit= join->unit->offset_limit_cnt; From 288eff45cba7e173d3f3a70a92ad13ef19ce6160 Mon Sep 17 00:00:00 2001 From: "jani@a193-229-222-105.elisa-laajakaista.fi" <> Date: Wed, 6 Apr 2005 21:55:34 +0300 Subject: [PATCH 53/83] Added missing file to Makefile.am --- mysql-test/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index f3efa24b628..34b1dd1a1fe 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -59,6 +59,7 @@ dist-hook: $(INSTALL_DATA) $(srcdir)/std_data/*.frm $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(distdir)/lib $(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib + $(INSTALL_DATA) $(srcdir)/*.supp $(distdir)/ install-data-local: $(mkinstalldirs) \ From 5cd866610df606253827d5495343365af0cc9134 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Wed, 6 Apr 2005 23:12:10 +0200 Subject: [PATCH 54/83] after merge fix --- mysql-test/r/user_var.result | 3 +-- mysql-test/t/user_var.test | 3 +-- ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp | 3 ++- strings/ctype-cp932.c | 4 +++- strings/ctype-eucjpms.c | 11 +++++++---- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index d36dca86e39..68eae111111 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -180,6 +180,5 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4); coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4) 2 2 2 2 set session @honk=99; -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 '@honk=99' at line 1 set one_shot @honk=99; -ERROR HY000: The SET ONE_SHOT syntax is reserved for purposes internal to the MySQL server +ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 49941bc81f3..ef360f2231d 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -116,7 +116,6 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4); # # Bug #9286 SESSION/GLOBAL should be disallowed for user variables # ---error 1064 set session @honk=99; ---error 1105 +--error 1382 set one_shot @honk=99; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp index c3f85cdebd5..3170d23499a 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp @@ -813,6 +813,7 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer, ndbrequire(i < regTabPtr->noOfCharsets); // not const in MySQL CHARSET_INFO* cs = regTabPtr->charsetArray[i]; + int not_used; const char* ssrc = (const char*)&inBuffer[tInBufIndex + 1]; Uint32 lb, len; if (! NdbSqlUtil::get_var_length(typeId, ssrc, bytes, lb, len)) { @@ -822,7 +823,7 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer, } // fast fix bug#7340 if (typeId != NDB_TYPE_TEXT && - (*cs->cset->well_formed_len)(cs, ssrc + lb, ssrc + lb + len, ZNIL) != len) { + (*cs->cset->well_formed_len)(cs, ssrc + lb, ssrc + lb + len, ZNIL, ¬_used) != len) { ljam(); terrorCode = ZINVALID_CHAR_FORMAT; return false; diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index c47f2c2d8ce..47bf1167c8c 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -5413,9 +5413,10 @@ uint my_numcells_cp932(CHARSET_INFO *cs __attribute__((unused)), */ static uint my_well_formed_len_cp932(CHARSET_INFO *cs __attribute__((unused)), - const char *b, const char *e, uint pos) + const char *b, const char *e, uint pos, int *error) { const char *b0= b; + *error= 0; while (pos && b < e) { /* @@ -5441,6 +5442,7 @@ uint my_well_formed_len_cp932(CHARSET_INFO *cs __attribute__((unused)), else { /* Wrong byte sequence */ + *error= 1; break; } } diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c index 8c8d237cf48..346b5ecdf6b 100644 --- a/strings/ctype-eucjpms.c +++ b/strings/ctype-eucjpms.c @@ -8380,17 +8380,18 @@ my_jisx0212_uni_onechar(int code){ /* EUC-JP encoding subcomponents: - [x00-x7F] # ASCII/JIS-Roman (one-byte/character) - [x8E][xA0-xDF] # half-width katakana (two bytes/char) - [x8F][xA1-xFE][xA1-xFE] # JIS X 0212-1990 (three bytes/char) + [x00-x7F] # ASCII/JIS-Roman (one-byte/character) + [x8E][xA0-xDF] # half-width katakana (two bytes/char) + [x8F][xA1-xFE][xA1-xFE] # JIS X 0212-1990 (three bytes/char) [xA1-xFE][xA1-xFE] # JIS X 0208:1997 (two bytes/char) */ static uint my_well_formed_len_eucjpms(CHARSET_INFO *cs __attribute__((unused)), - const char *beg, const char *end, uint pos) + const char *beg, const char *end, uint pos, int *error) { const uchar *b= (uchar *) beg; + *error=0; for ( ; pos && b < (uchar*) end; pos--, b++) { @@ -8408,6 +8409,7 @@ uint my_well_formed_len_eucjpms(CHARSET_INFO *cs __attribute__((unused)), { if (*b >= 0xA0 && *b <= 0xDF) continue; + *error=1; return chbeg - beg; /* invalid sequence */ } @@ -8421,6 +8423,7 @@ uint my_well_formed_len_eucjpms(CHARSET_INFO *cs __attribute__((unused)), if (ch >= 0xA1 && ch <= 0xFE && *b >= 0xA1 && *b <= 0xFE) /* [xA1-xFE][xA1-xFE] */ continue; + *error=1; return chbeg - beg; /* invalid sequence */ } return b - (uchar *) beg; From d85bed11215aff82e4d63b9c9e6e7fca29562a86 Mon Sep 17 00:00:00 2001 From: "dlenev@brandersnatch.localdomain" <> Date: Thu, 7 Apr 2005 01:40:29 +0400 Subject: [PATCH 55/83] Fix for bug #9566 "explicit LOCK TABLE and store procedures result in illegal state". We should not assume that mysql.proc table does not exist if we are unable to open it under LOCK TABLES or in prelocked mode (and remember this fact by setting mysql_proc_table_exists to zero). --- mysql-test/r/sp.result | 10 ++++++++++ mysql-test/t/sp.test | 23 +++++++++++++++++++++++ sql/sp.cc | 13 +++++++++---- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index daad032b854..cb0ae310ceb 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -2779,4 +2779,14 @@ a 3.2000 drop procedure bug8937| delete from t1| +drop procedure if exists bug9566| +create procedure bug9566() +begin +select * from t1; +end| +lock table t1 read| +call bug9566()| +ERROR HY000: Table 'proc' was not locked with LOCK TABLES +unlock tables| +drop procedure bug9566| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index a741a4af7d8..799e88a6615 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3397,6 +3397,29 @@ call bug8937()| drop procedure bug8937| delete from t1| +# +# BUG#9566: explicit LOCK TABLE and store procedures result in illegal state +# +# We should not think that mysql.proc table does not exist if we are unable +# to open it under LOCK TABLE or in prelocked mode. Probably this test +# should be removed when Monty will allow access to mysql.proc without +# locking it. +# +--disable_warnings +drop procedure if exists bug9566| +--enable_warnings +create procedure bug9566() +begin + select * from t1; +end| +lock table t1 read| +# This should fail because we forgot to lock mysql.proc table explicitly +--error 1100 +call bug9566()| +unlock tables| +# This should succeed +drop procedure bug9566| + # # BUG#NNNN: New bug synopsis diff --git a/sql/sp.cc b/sql/sp.cc index 23d389cd299..1956f32f2c6 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -70,9 +70,8 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, type, name->m_name.length, name->m_name.str)); /* - Speed up things if mysql.proc doesn't exists - mysql_proc_table_exists is set when on creates a stored procedure - or on flush privileges + Speed up things if mysql.proc doesn't exists. mysql_proc_table_exists + is set when we create or read stored procedure or on flush privileges. */ if (!mysql_proc_table_exists && ltype == TL_READ) DBUG_RETURN(SP_OPEN_TABLE_FAILED); @@ -98,7 +97,13 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, if (! (table= open_ltable(thd, &tables, ltype))) { *tablep= NULL; - mysql_proc_table_exists= 0; + /* + Under explicit LOCK TABLES or in prelocked mode we should not + say that mysql.proc table does not exist if we are unable to + open it since this condition may be transient. + */ + if (!(thd->locked_tables || thd->prelocked_mode)) + mysql_proc_table_exists= 0; DBUG_RETURN(SP_OPEN_TABLE_FAILED); } *opened= TRUE; From 8d05aa0f02bc0083261d1717bb875b5c11d24309 Mon Sep 17 00:00:00 2001 From: "dlenev@brandersnatch.localdomain" <> Date: Thu, 7 Apr 2005 11:57:47 +0400 Subject: [PATCH 56/83] Moved test for bug #9566 "explicit LOCK TABLE and store procedures result in illegal state" to sp-error.test. According to Per-Erik all SP related tests which should result in error should go into sp-error.test and not in sp.test, because we want to be able to run sp.test using normal client. --- mysql-test/r/sp-error.result | 10 ++++++++++ mysql-test/r/sp.result | 10 ---------- mysql-test/t/sp-error.test | 23 +++++++++++++++++++++++ mysql-test/t/sp.test | 23 ----------------------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index c979ee34df0..ff7d71b3384 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -503,4 +503,14 @@ ERROR 0A000: LOCK is not allowed in stored procedures create procedure bug6600() unlock table t1| ERROR 0A000: UNLOCK is not allowed in stored procedures +drop procedure if exists bug9566| +create procedure bug9566() +begin +select * from t1; +end| +lock table t1 read| +call bug9566()| +ERROR HY000: Table 'proc' was not locked with LOCK TABLES +unlock tables| +drop procedure bug9566| drop table t1| diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index cb0ae310ceb..daad032b854 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -2779,14 +2779,4 @@ a 3.2000 drop procedure bug8937| delete from t1| -drop procedure if exists bug9566| -create procedure bug9566() -begin -select * from t1; -end| -lock table t1 read| -call bug9566()| -ERROR HY000: Table 'proc' was not locked with LOCK TABLES -unlock tables| -drop procedure bug9566| drop table t1,t2; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 621700b732a..51776453730 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -696,6 +696,29 @@ create procedure bug6600() create procedure bug6600() unlock table t1| +# +# BUG#9566: explicit LOCK TABLE and store procedures result in illegal state +# +# We should not think that mysql.proc table does not exist if we are unable +# to open it under LOCK TABLE or in prelocked mode. Probably this test +# should be removed when Monty will allow access to mysql.proc without +# locking it. +# +--disable_warnings +drop procedure if exists bug9566| +--enable_warnings +create procedure bug9566() +begin + select * from t1; +end| +lock table t1 read| +# This should fail because we forgot to lock mysql.proc table explicitly +--error 1100 +call bug9566()| +unlock tables| +# This should succeed +drop procedure bug9566| + # # BUG#NNNN: New bug synopsis diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 799e88a6615..a741a4af7d8 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3397,29 +3397,6 @@ call bug8937()| drop procedure bug8937| delete from t1| -# -# BUG#9566: explicit LOCK TABLE and store procedures result in illegal state -# -# We should not think that mysql.proc table does not exist if we are unable -# to open it under LOCK TABLE or in prelocked mode. Probably this test -# should be removed when Monty will allow access to mysql.proc without -# locking it. -# ---disable_warnings -drop procedure if exists bug9566| ---enable_warnings -create procedure bug9566() -begin - select * from t1; -end| -lock table t1 read| -# This should fail because we forgot to lock mysql.proc table explicitly ---error 1100 -call bug9566()| -unlock tables| -# This should succeed -drop procedure bug9566| - # # BUG#NNNN: New bug synopsis From 934f458140dc970ccc4cdb4ebb094f38c8b651c9 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Thu, 7 Apr 2005 12:12:03 +0200 Subject: [PATCH 57/83] Added missing DBUG_RETURNs --- ndb/src/ndbapi/NdbDictionaryImpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index e88f76ef513..fb2e0d673cd 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -1501,7 +1501,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, if (col->m_autoIncrement) { if (haveAutoIncrement) { m_error.code = 4335; - return -1; + DBUG_RETURN(-1); } haveAutoIncrement = true; autoIncrementValue = col->m_autoIncrementInitialValue; @@ -1622,7 +1622,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, ret= createTable(&tSignal, ptr); if (ret) - return ret; + DBUG_RETURN(ret); if (haveAutoIncrement) { if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(), From 18354f457005c98112e51d02fa18f16feff50724 Mon Sep 17 00:00:00 2001 From: "jani@ua141d10.elisa.omakaista.fi" <> Date: Thu, 7 Apr 2005 13:20:15 +0300 Subject: [PATCH 58/83] A small fix to Makefile.am --- mysql-test/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 34b1dd1a1fe..9963074daf5 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -32,7 +32,7 @@ endif benchdir_root= $(prefix) testdir = $(benchdir_root)/mysql-test -EXTRA_SCRIPTS = mysql-test-run.sh mysql-test-run.pl install_test_db.sh +EXTRA_SCRIPTS = mysql-test-run.sh mysql-test-run.pl install_test_db.sh valgrind.supp EXTRA_DIST = $(EXTRA_SCRIPTS) test_SCRIPTS = mysql-test-run install_test_db test_DATA = std_data/client-key.pem std_data/client-cert.pem std_data/cacert.pem @@ -59,7 +59,6 @@ dist-hook: $(INSTALL_DATA) $(srcdir)/std_data/*.frm $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(distdir)/lib $(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib - $(INSTALL_DATA) $(srcdir)/*.supp $(distdir)/ install-data-local: $(mkinstalldirs) \ From b950bc210c64440c9bc12c9d8d77c9cf4a0b5ac4 Mon Sep 17 00:00:00 2001 From: "bar@mysql.com" <> Date: Thu, 7 Apr 2005 16:14:45 +0500 Subject: [PATCH 59/83] ctype-eucjpms.c: After merge fix. --- strings/ctype-eucjpms.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c index 346b5ecdf6b..ab12446754a 100644 --- a/strings/ctype-eucjpms.c +++ b/strings/ctype-eucjpms.c @@ -8417,7 +8417,10 @@ uint my_well_formed_len_eucjpms(CHARSET_INFO *cs __attribute__((unused)), { ch= *b++; if (b >= (uchar*) end) + { + *error= 1; return chbeg - beg; /* unexpected EOL */ + } } if (ch >= 0xA1 && ch <= 0xFE && From 9911194a1373181aaf6bbd736d487f75ea7aca5a Mon Sep 17 00:00:00 2001 From: "magnus@msdesk.mysql.com" <> Date: Thu, 7 Apr 2005 14:39:30 +0200 Subject: [PATCH 60/83] Fix linking problem on bsd53 - See article http://archive.netbsd.se/?ml=freebsd-current&a=2004-07&m=257561 or http://www.geocrawler.com/archives/3/254/2003/3/450/10409564/ --- configure.in | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure.in b/configure.in index c7e93c9676a..01f669a0d1b 100644 --- a/configure.in +++ b/configure.in @@ -351,6 +351,15 @@ then if echo $CXX | grep gcc > /dev/null 2>&1 then GCC_VERSION=`gcc -v 2>&1 | grep version | sed -e 's/[[^0-9. ]]//g; s/^ *//g; s/ .*//g'` + case $SYSTEM_TYPE in + *freebsd*) + # The libsupc++ library on freebsd with gcc 3.4.2 is dependent on + # libstdc++, disable it since other solution works fine + GCC_VERSION="NOSUPCPP_$GCC_VERSION" + ;; + *) + ;; + esac echo "Using gcc version '$GCC_VERSION'" case "$GCC_VERSION" in 3.4.*|3.5.*) From b591d3434a16f079d012cb0cdb4853906e8f1470 Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Thu, 7 Apr 2005 17:42:32 +0400 Subject: [PATCH 61/83] BUG#8877: Post-merge fixes. --- sql/sql_select.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 21e8316bb9e..09fb0b3c5ae 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2231,6 +2231,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, if (s->dependent & table->map) s->dependent |= table->reginfo.join_tab->dependent; } + if (s->dependent) + s->table->maybe_null= 1; } /* Catch illegal cross references for outer joins */ for (i= 0, s= stat ; i < table_count ; i++, s++) @@ -2623,6 +2625,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, static void add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, + Field *field, bool eq_func, Item **value, uint num_values, table_map usable_tables) { uint exists_optimize= 0; @@ -2758,7 +2761,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, static void add_key_equal_fields(KEY_FIELD **key_fields, uint and_level, - COND *cond, Item_field *field_item, + Item_func *cond, Item_field *field_item, bool eq_func, Item **val, uint num_values, table_map usable_tables) { @@ -2899,7 +2902,7 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level, */ while ((item= it++)) { - add_key_field(key_fields, *and_level, cond, item->field, + add_key_field(key_fields, *and_level, cond_func, item->field, TRUE, &const_item, 1, usable_tables); } } @@ -2919,7 +2922,7 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level, { if (!field->eq(item->field)) { - add_key_field(key_fields, *and_level, cond, field, + add_key_field(key_fields, *and_level, cond_func, field, TRUE, (Item **) &item, 1, usable_tables); } } @@ -3139,7 +3142,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, { NESTED_JOIN *nested_join= embedding->nested_join; if (nested_join->join_list.head() == tab) - add_key_fields(join_tab, &end, &and_level, embedding->on_expr, + add_key_fields(&end, &and_level, embedding->on_expr, nested_join->used_tables); } } @@ -5174,7 +5177,7 @@ static void add_not_null_conds(JOIN *join) null_rej->quick_fix_field(); DBUG_EXECUTE("where",print_where(null_rej, - referred_tab->table->table_name);); + referred_tab->table->alias);); add_cond_and_fix(&referred_tab->select_cond, null_rej); } } @@ -5454,7 +5457,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) tab->select_cond= sel->cond= NULL; sel->head=tab->table; - DBUG_EXECUTE("where",print_where(tmp,tab->table->table_name);); + DBUG_EXECUTE("where",print_where(tmp,tab->table->alias);); if (tab->quick) { /* Use quick key read if it's a constant and it's not used From 0cd5877b025f77bf8a33b9ac6dd8eaea9cc6edcb Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Thu, 7 Apr 2005 17:44:48 +0400 Subject: [PATCH 62/83] Post-review fixes: local variable renamed --- sql/sql_select.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 248ed06b6b3..8a668b64edf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3532,14 +3532,14 @@ static void add_not_null_conds(JOIN *join) DBUG_ASSERT(item->type() == Item::FIELD_ITEM); Item_field *not_null_item= (Item_field*)item; JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; - Item_func_isnotnull *null_rej; - if (!(null_rej= new Item_func_isnotnull(not_null_item))) + Item_func_isnotnull *notnull; + if (!(notnull= new Item_func_isnotnull(not_null_item))) DBUG_VOID_RETURN; - null_rej->quick_fix_field(); - DBUG_EXECUTE("where",print_where(null_rej, + notnull->quick_fix_field(); + DBUG_EXECUTE("where",print_where(notnull, referred_tab->table->table_name);); - add_cond_and_fix(&referred_tab->select_cond, null_rej); + add_cond_and_fix(&referred_tab->select_cond, notnull); } } } From 89b140340cf4768d2f693d0d6f264fce429a83c7 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Thu, 7 Apr 2005 17:44:09 +0200 Subject: [PATCH 63/83] Fix for Bug #9675 Auto-increment not working with INSERT..SELECT and NDB storage --- mysql-test/r/ndb_basic.result | 30 +++++++++++++++++++++++++++++ mysql-test/t/ndb_basic.test | 25 ++++++++++++++++++++++++ ndb/src/ndbapi/Ndb.cpp | 36 +++++++++++++++++++++-------------- sql/ha_ndbcluster.cc | 7 ++++++- 4 files changed, 83 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index a6396080ef0..12f9c3742e5 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -607,3 +607,33 @@ primary key (a)) engine=ndb max_rows=1; drop table t1; +create table t1 +(counter int(64) NOT NULL auto_increment, +datavalue char(40) default 'XXXX', +primary key (counter) +) ENGINE=ndbcluster; +insert into t1 (datavalue) values ('newval'); +insert into t1 (datavalue) values ('newval'); +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +3 newval +4 newval +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +3 newval +4 newval +35 newval +36 newval +37 newval +38 newval +drop table t1; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index f460c573a9d..35e1ddc5ebf 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -577,3 +577,28 @@ create table t1 engine=ndb max_rows=1; drop table t1; + +# +# Test auto_increment +# + +connect (con1,localhost,,,test); +connect (con2,localhost,,,test); + +create table t1 + (counter int(64) NOT NULL auto_increment, + datavalue char(40) default 'XXXX', + primary key (counter) + ) ENGINE=ndbcluster; + +connection con1; +insert into t1 (datavalue) values ('newval'); +insert into t1 (datavalue) values ('newval'); +select * from t1 order by counter; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; +connection con2; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; + +drop table t1; diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index b5493622b70..6390a1b50b5 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -722,26 +722,28 @@ Remark: Returns a new TupleId to the application. Uint64 Ndb::getAutoIncrementValue(const char* aTableName, Uint32 cacheSize) { - DEBUG_TRACE("getAutoIncrementValue"); + DBUG_ENTER("getAutoIncrementValue"); const char * internalTableName = internalizeTableName(aTableName); Ndb_local_table_info *info= theDictionary->get_local_table_info(internalTableName, false); if (info == 0) - return ~0; + DBUG_RETURN(~0); const NdbTableImpl *table= info->m_table_impl; Uint64 tupleId = getTupleIdFromNdb(table->m_tableId, cacheSize); - return tupleId; + DBUG_PRINT("info", ("value %u", tupleId)); + DBUG_RETURN(tupleId); } Uint64 Ndb::getAutoIncrementValue(const NdbDictionary::Table * aTable, Uint32 cacheSize) { - DEBUG_TRACE("getAutoIncrementValue"); + DBUG_ENTER("getAutoIncrementValue"); if (aTable == 0) - return ~0; + DBUG_RETURN(~0); const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable); Uint64 tupleId = getTupleIdFromNdb(table->m_tableId, cacheSize); - return tupleId; + DBUG_PRINT("info", ("value %u", tupleId)); + DBUG_RETURN(tupleId); } Uint64 @@ -756,39 +758,45 @@ Ndb::getTupleIdFromNdb(const char* aTableName, Uint32 cacheSize) Uint64 Ndb::getTupleIdFromNdb(Uint32 aTableId, Uint32 cacheSize) { + DBUG_ENTER("getTupleIdFromNdb"); if ( theFirstTupleId[aTableId] != theLastTupleId[aTableId] ) { theFirstTupleId[aTableId]++; - return theFirstTupleId[aTableId]; + DBUG_PRINT("info", ("next cached value %u", theFirstTupleId[aTableId])); + DBUG_RETURN(theFirstTupleId[aTableId]); } else // theFirstTupleId == theLastTupleId { - return opTupleIdOnNdb(aTableId, cacheSize, 0); + DBUG_PRINT("info",("reading %u values from database", + (cacheSize == 0) ? 1 : cacheSize)); + DBUG_RETURN(opTupleIdOnNdb(aTableId, (cacheSize == 0) ? 1 : cacheSize, 0)); } } Uint64 Ndb::readAutoIncrementValue(const char* aTableName) { - DEBUG_TRACE("readtAutoIncrementValue"); + DBUG_ENTER("readtAutoIncrementValue"); const NdbTableImpl* table = theDictionary->getTable(aTableName); if (table == 0) { theError= theDictionary->getNdbError(); - return ~0; + DBUG_RETURN(~0); } Uint64 tupleId = readTupleIdFromNdb(table->m_tableId); - return tupleId; + DBUG_PRINT("info", ("value %u", tupleId)); + DBUG_RETURN(tupleId); } Uint64 Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable) { - DEBUG_TRACE("readtAutoIncrementValue"); + DBUG_ENTER("readtAutoIncrementValue"); if (aTable == 0) - return ~0; + DBUG_RETURN(~0); const NdbTableImpl* table = & NdbTableImpl::getImpl(*aTable); Uint64 tupleId = readTupleIdFromNdb(table->m_tableId); - return tupleId; + DBUG_PRINT("info", ("value %u", tupleId)); + DBUG_RETURN(tupleId); } Uint64 diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 7025ac2cd1a..31b16d58b62 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2920,7 +2920,11 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows) DBUG_PRINT("enter", ("rows: %d", (int)rows)); m_rows_inserted= 0; - m_rows_to_insert= rows; + if (rows == 0) + /* We don't know how many will be inserted, guess */ + m_rows_to_insert= m_autoincrement_prefetch; + else + m_rows_to_insert= rows; /* Calculate how many rows that should be inserted @@ -3929,6 +3933,7 @@ longlong ha_ndbcluster::get_auto_increment() DBUG_ENTER("get_auto_increment"); DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); Ndb *ndb= get_ndb(); + int cache_size= (m_rows_to_insert - m_rows_inserted < m_autoincrement_prefetch) ? m_rows_to_insert - m_rows_inserted From 780202f130f97a358d4cbce3388e840664daf176 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 7 Apr 2005 19:24:14 +0300 Subject: [PATCH 64/83] Moved some old test and added a new test to only be run with mysql-test-run --big Fixed warnings by valgrind for sum_distinct.test Enable buffered-record-reads after filesort for InnoDB tables with short primary key Enabled sort-with-data for MyISAM temporary files --- .bzrignore | 1 + client/mysqltest.c | 11 ++- mysql-test/include/big_test.inc | 4 + mysql-test/mysql-test-run.sh | 4 +- mysql-test/r/heap.result | 60 +++++++-------- mysql-test/r/innodb-big.result | 34 +++++++++ mysql-test/r/sum_distinct-big.result | 108 +++++++++++++++++++++++++++ mysql-test/r/sum_distinct.result | 106 -------------------------- mysql-test/t/heap.test | 6 +- mysql-test/t/innodb-big.test | 46 ++++++++++++ mysql-test/t/sum_distinct-big.test | 67 +++++++++++++++++ mysql-test/t/sum_distinct.test | 59 --------------- sql/filesort.cc | 33 ++++---- sql/ha_innodb.h | 1 - sql/handler.h | 24 ++++-- sql/mysql_priv.h | 2 +- sql/records.cc | 6 +- sql/sql_select.cc | 2 + 18 files changed, 346 insertions(+), 228 deletions(-) create mode 100644 mysql-test/include/big_test.inc create mode 100644 mysql-test/r/innodb-big.result create mode 100644 mysql-test/r/sum_distinct-big.result create mode 100644 mysql-test/t/innodb-big.test create mode 100644 mysql-test/t/sum_distinct-big.test diff --git a/.bzrignore b/.bzrignore index eae47b882d0..cfe38741074 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1109,3 +1109,4 @@ vio/viotest-ssl VC++Files/client/mysql_amd64.dsp client/mysqltestmanager-pwgen client/mysqltestmanagerc +tools/mysqltestmanager diff --git a/client/mysqltest.c b/client/mysqltest.c index 3386118014a..2b7000f0d88 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -645,6 +645,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname) { DBUG_PRINT("info",("Size differs: result size: %u file size: %u", ds->length, stat_info.st_size)); + DBUG_PRINT("info",("result: '%s'", ds->str)); DBUG_RETURN(2); } if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME)))) @@ -3623,8 +3624,8 @@ static void init_var_hash(MYSQL *mysql) if (hash_init(&var_hash, charset_info, 1024, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); - if (opt_big_test) - my_hash_insert(&var_hash, (byte*) var_init(0,"BIG_TEST", 0, "1",0)); + my_hash_insert(&var_hash, (byte*) var_init(0,"BIG_TEST", 0, + (opt_big_test) ? "1" : "0", 0)); v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0); my_hash_insert(&var_hash, (byte*) v); v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0); @@ -3793,6 +3794,12 @@ int main(int argc, char **argv) if (q->query == q->query_buf) q->query += q->first_word_len + 1; display_result_vertically= (q->type==Q_QUERY_VERTICAL); + if (save_file[0]) + { + strmov(q->record_file,save_file); + q->require_file=require_file; + save_file[0]=0; + } error|= run_query(&cur_con->mysql, q, QUERY_REAP|QUERY_SEND); display_result_vertically= old_display_result_vertically; break; diff --git a/mysql-test/include/big_test.inc b/mysql-test/include/big_test.inc new file mode 100644 index 00000000000..6b149540c96 --- /dev/null +++ b/mysql-test/include/big_test.inc @@ -0,0 +1,4 @@ +--require r/big_test.require +disable_query_log; +eval select $BIG_TEST as using_big_test; +enable_query_log; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 0ad8536f579..5fb4d99d4f4 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -1179,7 +1179,7 @@ start_master() --default-character-set=$CHARACTER_SET \ --tmpdir=$MYSQL_TMP_DIR \ --language=$LANGUAGE \ - --innodb_data_file_path=ibdata1:50M \ + --innodb_data_file_path=ibdata1:128M:autoextend \ --open-files-limit=1024 \ $MASTER_40_ARGS \ $SMALL_SERVER \ @@ -1200,7 +1200,7 @@ start_master() $USE_NDBCLUSTER \ --tmpdir=$MYSQL_TMP_DIR \ --language=$LANGUAGE \ - --innodb_data_file_path=ibdata1:50M \ + --innodb_data_file_path=ibdata1:128M:autoextend \ $MASTER_40_ARGS \ $SMALL_SERVER \ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \ diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index 631bd8c713c..702daf98214 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -436,30 +436,30 @@ f 10 g 10 h 10 i 10 -select sql_big_result v,count(t) from t1 group by v limit 10; -v count(t) +select sql_big_result trim(v),count(t) from t1 group by v limit 10; +trim(v) count(t) a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 h 10 -i 10 -select sql_big_result v,count(c) from t1 group by v limit 10; -v count(c) +i 10 +select sql_big_result trim(v),count(c) from t1 group by v limit 10; +trim(v) count(c) a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 h 10 -i 10 +i 10 select c,count(*) from t1 group by c limit 10; c count(*) a 1 @@ -520,18 +520,18 @@ f 10 g 10 h 10 i 10 -select sql_big_result t,count(t) from t1 group by t limit 10; -t count(t) +select sql_big_result trim(t),count(t) from t1 group by t limit 10; +trim(t) count(t) a 1 -a 10 -b 10 -c 10 -d 10 -e 10 -f 10 -g 10 +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 h 10 -i 10 +i 10 drop table t1; create table t1 (a char(10), unique (a)); insert into t1 values ('a'); diff --git a/mysql-test/r/innodb-big.result b/mysql-test/r/innodb-big.result new file mode 100644 index 00000000000..19204b7cc65 --- /dev/null +++ b/mysql-test/r/innodb-big.result @@ -0,0 +1,34 @@ +DROP TABLE IF EXISTS t1, t2, t3, t4; +CREATE TABLE t1 (id INTEGER) ENGINE=MYISAM; +CREATE TABLE t2 (id INTEGER primary key) ENGINE=INNODB; +CREATE TABLE t3 (a char(32) primary key,id INTEGER) ENGINE=INNODB; +CREATE TABLE t4 (a char(32) primary key,id INTEGER) ENGINE=MYISAM; +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t1 SELECT id+1 FROM t1; +INSERT INTO t1 SELECT id+2 FROM t1; +INSERT INTO t1 SELECT id+4 FROM t1; +INSERT INTO t1 SELECT id+8 FROM t1; +INSERT INTO t1 SELECT id+16 FROM t1; +INSERT INTO t1 SELECT id+32 FROM t1; +INSERT INTO t1 SELECT id+64 FROM t1; +INSERT INTO t1 SELECT id+128 FROM t1; +INSERT INTO t1 SELECT id+256 FROM t1; +INSERT INTO t1 SELECT id+512 FROM t1; +INSERT INTO t1 SELECT id+1024 FROM t1; +INSERT INTO t1 SELECT id+2048 FROM t1; +INSERT INTO t1 SELECT id+4096 FROM t1; +INSERT INTO t1 SELECT id+8192 FROM t1; +INSERT INTO t1 SELECT id+16384 FROM t1; +INSERT INTO t1 SELECT id+32768 FROM t1; +INSERT INTO t1 SELECT id+65536 FROM t1; +INSERT INTO t1 SELECT id+131072 FROM t1; +INSERT INTO t1 SELECT id+262144 FROM t1; +INSERT INTO t1 SELECT id+524288 FROM t1; +INSERT INTO t1 SELECT id+1048576 FROM t1; +INSERT INTO t2 SELECT * FROM t1; +INSERT INTO t3 SELECT concat(id),id from t2 ORDER BY -id; +INSERT INTO t4 SELECT * from t3 ORDER BY concat(a); +select sum(id) from t3; +sum(id) +2199024304128 +drop table t1,t2,t3,t4; diff --git a/mysql-test/r/sum_distinct-big.result b/mysql-test/r/sum_distinct-big.result new file mode 100644 index 00000000000..06bfc6b1f78 --- /dev/null +++ b/mysql-test/r/sum_distinct-big.result @@ -0,0 +1,108 @@ +using_big_test +0 +CREATE TABLE t1 (id INTEGER); +CREATE TABLE t2 (id INTEGER); +INSERT INTO t1 (id) VALUES (1), (1), (1),(1); +INSERT INTO t1 (id) SELECT id FROM t1; +/* 8 */ +INSERT INTO t1 (id) SELECT id FROM t1; +/* 12 */ +INSERT INTO t1 (id) SELECT id FROM t1; +/* 16 */ +INSERT INTO t1 (id) SELECT id FROM t1; +/* 20 */ +INSERT INTO t1 (id) SELECT id FROM t1; +/* 24 */ +INSERT INTO t1 SELECT id+1 FROM t1; +INSERT INTO t1 SELECT id+2 FROM t1; +INSERT INTO t1 SELECT id+4 FROM t1; +INSERT INTO t1 SELECT id+8 FROM t1; +INSERT INTO t1 SELECT id+16 FROM t1; +INSERT INTO t1 SELECT id+32 FROM t1; +INSERT INTO t1 SELECT id+64 FROM t1; +INSERT INTO t1 SELECT id+128 FROM t1; +INSERT INTO t1 SELECT id+256 FROM t1; +INSERT INTO t1 SELECT id+512 FROM t1; +SELECT AVG(DISTINCT id) FROM t1 GROUP BY id % 13; +AVG(DISTINCT id) +513.5000 +508.0000 +509.0000 +510.0000 +511.0000 +512.0000 +513.0000 +514.0000 +515.0000 +516.0000 +517.0000 +511.5000 +512.5000 +SELECT SUM(DISTINCT id)/COUNT(DISTINCT id) FROM t1 GROUP BY id % 13; +SUM(DISTINCT id)/COUNT(DISTINCT id) +513.50000 +508.00000 +509.00000 +510.00000 +511.00000 +512.00000 +513.00000 +514.00000 +515.00000 +516.00000 +517.00000 +511.50000 +512.50000 +INSERT INTO t1 SELECT id+1024 FROM t1; +INSERT INTO t1 SELECT id+2048 FROM t1; +INSERT INTO t1 SELECT id+4096 FROM t1; +INSERT INTO t1 SELECT id+8192 FROM t1; +INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand(); +SELECT SUM(DISTINCT id) sm FROM t1; +sm +134225920 +SELECT SUM(DISTINCT id) sm FROM t2; +sm +134225920 +SELECT SUM(DISTINCT id) sm FROM t1 group by id % 13; +sm +10327590 +10328851 +10330112 +10331373 +10332634 +10317510 +10318770 +10320030 +10321290 +10322550 +10323810 +10325070 +10326330 +SET max_heap_table_size=16384; +SHOW variables LIKE 'max_heap_table_size'; +Variable_name Value +max_heap_table_size 16384 +SELECT SUM(DISTINCT id) sm FROM t1; +sm +134225920 +SELECT SUM(DISTINCT id) sm FROM t2; +sm +134225920 +SELECT SUM(DISTINCT id) sm FROM t1 GROUP BY id % 13; +sm +10327590 +10328851 +10330112 +10331373 +10332634 +10317510 +10318770 +10320030 +10321290 +10322550 +10323810 +10325070 +10326330 +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/r/sum_distinct.result b/mysql-test/r/sum_distinct.result index 0591943e800..c615817f52d 100644 --- a/mysql-test/r/sum_distinct.result +++ b/mysql-test/r/sum_distinct.result @@ -95,109 +95,3 @@ SELECT SUM(DISTINCT id % 11) FROM t1; SUM(DISTINCT id % 11) 55 DROP TABLE t1; -CREATE TABLE t1 (id INTEGER); -CREATE TABLE t2 (id INTEGER); -INSERT INTO t1 (id) VALUES (1), (1), (1),(1); -INSERT INTO t1 (id) SELECT id FROM t1; -/* 8 */ -INSERT INTO t1 (id) SELECT id FROM t1; -/* 12 */ -INSERT INTO t1 (id) SELECT id FROM t1; -/* 16 */ -INSERT INTO t1 (id) SELECT id FROM t1; -/* 20 */ -INSERT INTO t1 (id) SELECT id FROM t1; -/* 24 */ -INSERT INTO t1 SELECT id+1 FROM t1; -INSERT INTO t1 SELECT id+2 FROM t1; -INSERT INTO t1 SELECT id+4 FROM t1; -INSERT INTO t1 SELECT id+8 FROM t1; -INSERT INTO t1 SELECT id+16 FROM t1; -INSERT INTO t1 SELECT id+32 FROM t1; -INSERT INTO t1 SELECT id+64 FROM t1; -INSERT INTO t1 SELECT id+128 FROM t1; -INSERT INTO t1 SELECT id+256 FROM t1; -INSERT INTO t1 SELECT id+512 FROM t1; -SELECT AVG(DISTINCT id) FROM t1 GROUP BY id % 13; -AVG(DISTINCT id) -513.5000 -508.0000 -509.0000 -510.0000 -511.0000 -512.0000 -513.0000 -514.0000 -515.0000 -516.0000 -517.0000 -511.5000 -512.5000 -SELECT SUM(DISTINCT id)/COUNT(DISTINCT id) FROM t1 GROUP BY id % 13; -SUM(DISTINCT id)/COUNT(DISTINCT id) -513.50000 -508.00000 -509.00000 -510.00000 -511.00000 -512.00000 -513.00000 -514.00000 -515.00000 -516.00000 -517.00000 -511.50000 -512.50000 -INSERT INTO t1 SELECT id+1024 FROM t1; -INSERT INTO t1 SELECT id+2048 FROM t1; -INSERT INTO t1 SELECT id+4096 FROM t1; -INSERT INTO t1 SELECT id+8192 FROM t1; -INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand(); -SELECT SUM(DISTINCT id) sm FROM t1; -sm -134225920 -SELECT SUM(DISTINCT id) sm FROM t2; -sm -134225920 -SELECT SUM(DISTINCT id) sm FROM t1 group by id % 13; -sm -10327590 -10328851 -10330112 -10331373 -10332634 -10317510 -10318770 -10320030 -10321290 -10322550 -10323810 -10325070 -10326330 -SET max_heap_table_size=16384; -SHOW variables LIKE 'max_heap_table_size'; -Variable_name Value -max_heap_table_size 16384 -SELECT SUM(DISTINCT id) sm FROM t1; -sm -134225920 -SELECT SUM(DISTINCT id) sm FROM t2; -sm -134225920 -SELECT SUM(DISTINCT id) sm FROM t1 GROUP BY id % 13; -sm -10327590 -10328851 -10330112 -10331373 -10332634 -10317510 -10318770 -10320030 -10321290 -10322550 -10323810 -10325070 -10326330 -DROP TABLE t1; -DROP TABLE t2; diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test index c36474bda30..ca4a8beb527 100644 --- a/mysql-test/t/heap.test +++ b/mysql-test/t/heap.test @@ -280,14 +280,14 @@ explain select * from t1 where v='a'; select v,count(*) from t1 group by v limit 10; select v,count(t) from t1 group by v limit 10; select v,count(c) from t1 group by v limit 10; -select sql_big_result v,count(t) from t1 group by v limit 10; -select sql_big_result v,count(c) from t1 group by v limit 10; +select sql_big_result trim(v),count(t) from t1 group by v limit 10; +select sql_big_result trim(v),count(c) from t1 group by v limit 10; select c,count(*) from t1 group by c limit 10; select c,count(t) from t1 group by c limit 10; select sql_big_result c,count(t) from t1 group by c limit 10; select t,count(*) from t1 group by t limit 10; select t,count(t) from t1 group by t limit 10; -select sql_big_result t,count(t) from t1 group by t limit 10; +select sql_big_result trim(t),count(t) from t1 group by t limit 10; drop table t1; # diff --git a/mysql-test/t/innodb-big.test b/mysql-test/t/innodb-big.test new file mode 100644 index 00000000000..ade69ffdb45 --- /dev/null +++ b/mysql-test/t/innodb-big.test @@ -0,0 +1,46 @@ +# +# Test some things that takes a long time + +-- source include/big_test.inc +-- source include/have_innodb.inc + +--disable_warnings +DROP TABLE IF EXISTS t1, t2, t3, t4; +--enable_warnings + +# +# Test test how filesort and buffered-record-reads works with innodb +# + +CREATE TABLE t1 (id INTEGER) ENGINE=MYISAM; +CREATE TABLE t2 (id INTEGER primary key) ENGINE=INNODB; +CREATE TABLE t3 (a char(32) primary key,id INTEGER) ENGINE=INNODB; +CREATE TABLE t4 (a char(32) primary key,id INTEGER) ENGINE=MYISAM; + +INSERT INTO t1 (id) VALUES (1); +INSERT INTO t1 SELECT id+1 FROM t1; +INSERT INTO t1 SELECT id+2 FROM t1; +INSERT INTO t1 SELECT id+4 FROM t1; +INSERT INTO t1 SELECT id+8 FROM t1; +INSERT INTO t1 SELECT id+16 FROM t1; +INSERT INTO t1 SELECT id+32 FROM t1; +INSERT INTO t1 SELECT id+64 FROM t1; +INSERT INTO t1 SELECT id+128 FROM t1; +INSERT INTO t1 SELECT id+256 FROM t1; +INSERT INTO t1 SELECT id+512 FROM t1; +INSERT INTO t1 SELECT id+1024 FROM t1; +INSERT INTO t1 SELECT id+2048 FROM t1; +INSERT INTO t1 SELECT id+4096 FROM t1; +INSERT INTO t1 SELECT id+8192 FROM t1; +INSERT INTO t1 SELECT id+16384 FROM t1; +INSERT INTO t1 SELECT id+32768 FROM t1; +INSERT INTO t1 SELECT id+65536 FROM t1; +INSERT INTO t1 SELECT id+131072 FROM t1; +INSERT INTO t1 SELECT id+262144 FROM t1; +INSERT INTO t1 SELECT id+524288 FROM t1; +INSERT INTO t1 SELECT id+1048576 FROM t1; +INSERT INTO t2 SELECT * FROM t1; +INSERT INTO t3 SELECT concat(id),id from t2 ORDER BY -id; +INSERT INTO t4 SELECT * from t3 ORDER BY concat(a); +select sum(id) from t3; +drop table t1,t2,t3,t4; diff --git a/mysql-test/t/sum_distinct-big.test b/mysql-test/t/sum_distinct-big.test new file mode 100644 index 00000000000..0859f4b3d89 --- /dev/null +++ b/mysql-test/t/sum_distinct-big.test @@ -0,0 +1,67 @@ +# +# Various tests for SUM(DISTINCT ...) +# + +--source include/big_test.inc +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +# +# Test the case when distinct values doesn't fit in memory and +# filesort is used (see uniques.cc:merge_walk) +# + +CREATE TABLE t1 (id INTEGER); +CREATE TABLE t2 (id INTEGER); + +INSERT INTO t1 (id) VALUES (1), (1), (1),(1); +INSERT INTO t1 (id) SELECT id FROM t1; /* 8 */ +INSERT INTO t1 (id) SELECT id FROM t1; /* 12 */ +INSERT INTO t1 (id) SELECT id FROM t1; /* 16 */ +INSERT INTO t1 (id) SELECT id FROM t1; /* 20 */ +INSERT INTO t1 (id) SELECT id FROM t1; /* 24 */ +INSERT INTO t1 SELECT id+1 FROM t1; +INSERT INTO t1 SELECT id+2 FROM t1; +INSERT INTO t1 SELECT id+4 FROM t1; +INSERT INTO t1 SELECT id+8 FROM t1; +INSERT INTO t1 SELECT id+16 FROM t1; +INSERT INTO t1 SELECT id+32 FROM t1; +INSERT INTO t1 SELECT id+64 FROM t1; +INSERT INTO t1 SELECT id+128 FROM t1; +INSERT INTO t1 SELECT id+256 FROM t1; +INSERT INTO t1 SELECT id+512 FROM t1; + +# Just test that AVG(DISTINCT) is there +SELECT AVG(DISTINCT id) FROM t1 GROUP BY id % 13; +SELECT SUM(DISTINCT id)/COUNT(DISTINCT id) FROM t1 GROUP BY id % 13; + +INSERT INTO t1 SELECT id+1024 FROM t1; +INSERT INTO t1 SELECT id+2048 FROM t1; +INSERT INTO t1 SELECT id+4096 FROM t1; +INSERT INTO t1 SELECT id+8192 FROM t1; +INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand(); + +# SELECT '++++++++++++++++++++++++++++++++++++++++++++++++++'; + +SELECT SUM(DISTINCT id) sm FROM t1; +SELECT SUM(DISTINCT id) sm FROM t2; +SELECT SUM(DISTINCT id) sm FROM t1 group by id % 13; + +# this limit for max_heap_table_size is set to force testing the case, when +# all distinct sum values can not fit in memory and must be stored in a +# temporary table + +SET max_heap_table_size=16384; + +# to check that max_heap_table_size was actually set (hard limit for minimum +# max_heap_table_size is set in mysqld.cc): + +SHOW variables LIKE 'max_heap_table_size'; + +SELECT SUM(DISTINCT id) sm FROM t1; +SELECT SUM(DISTINCT id) sm FROM t2; +SELECT SUM(DISTINCT id) sm FROM t1 GROUP BY id % 13; + +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/t/sum_distinct.test b/mysql-test/t/sum_distinct.test index 3b9f12354e8..c58155a8e25 100644 --- a/mysql-test/t/sum_distinct.test +++ b/mysql-test/t/sum_distinct.test @@ -93,62 +93,3 @@ SELECT SUM(DISTINCT id) FROM t1; SELECT SUM(DISTINCT id % 11) FROM t1; DROP TABLE t1; - -# -# Test the case when distinct values doesn't fit in memory and -# filesort is used (see uniques.cc:merge_walk) -# - -CREATE TABLE t1 (id INTEGER); -CREATE TABLE t2 (id INTEGER); - -INSERT INTO t1 (id) VALUES (1), (1), (1),(1); -INSERT INTO t1 (id) SELECT id FROM t1; /* 8 */ -INSERT INTO t1 (id) SELECT id FROM t1; /* 12 */ -INSERT INTO t1 (id) SELECT id FROM t1; /* 16 */ -INSERT INTO t1 (id) SELECT id FROM t1; /* 20 */ -INSERT INTO t1 (id) SELECT id FROM t1; /* 24 */ -INSERT INTO t1 SELECT id+1 FROM t1; -INSERT INTO t1 SELECT id+2 FROM t1; -INSERT INTO t1 SELECT id+4 FROM t1; -INSERT INTO t1 SELECT id+8 FROM t1; -INSERT INTO t1 SELECT id+16 FROM t1; -INSERT INTO t1 SELECT id+32 FROM t1; -INSERT INTO t1 SELECT id+64 FROM t1; -INSERT INTO t1 SELECT id+128 FROM t1; -INSERT INTO t1 SELECT id+256 FROM t1; -INSERT INTO t1 SELECT id+512 FROM t1; - -# Just test that AVG(DISTINCT) is there -SELECT AVG(DISTINCT id) FROM t1 GROUP BY id % 13; -SELECT SUM(DISTINCT id)/COUNT(DISTINCT id) FROM t1 GROUP BY id % 13; - -INSERT INTO t1 SELECT id+1024 FROM t1; -INSERT INTO t1 SELECT id+2048 FROM t1; -INSERT INTO t1 SELECT id+4096 FROM t1; -INSERT INTO t1 SELECT id+8192 FROM t1; -INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand(); - -# SELECT '++++++++++++++++++++++++++++++++++++++++++++++++++'; - -SELECT SUM(DISTINCT id) sm FROM t1; -SELECT SUM(DISTINCT id) sm FROM t2; -SELECT SUM(DISTINCT id) sm FROM t1 group by id % 13; - -# this limit for max_heap_table_size is set to force testing the case, when -# all distinct sum values can not fit in memory and must be stored in a -# temporary table - -SET max_heap_table_size=16384; - -# to check that max_heap_table_size was actually set (hard limit for minimum -# max_heap_table_size is set in mysqld.cc): - -SHOW variables LIKE 'max_heap_table_size'; - -SELECT SUM(DISTINCT id) sm FROM t1; -SELECT SUM(DISTINCT id) sm FROM t2; -SELECT SUM(DISTINCT id) sm FROM t1 GROUP BY id % 13; - -DROP TABLE t1; -DROP TABLE t2; diff --git a/sql/filesort.cc b/sql/filesort.cc index c50f1daa6ef..30ebd8d59e1 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -127,7 +127,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, param.ref_length= table->file->ref_length; param.addon_field= 0; param.addon_length= 0; - if (!(table->s->tmp_table || table->fulltext_searched)) + if (!(table->file->table_flags() & HA_FAST_KEY_READ) && + !table->fulltext_searched) { /* Get the descriptors of all fields whose values are appended @@ -1301,27 +1302,29 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength) uint length= 0; uint fields= 0; uint null_fields= 0; - - /* - If there is a reference to a field in the query add it - to the the set of appended fields. - Note for future refinement: - This this a too strong condition. - Actually we need only the fields referred in the - result set. And for some of them it makes sense to use - the values directly from sorted fields. + query_id_t query_id= thd->query_id; + /* + If there is a reference to a field in the query add it + to the the set of appended fields. + Note for future refinement: + This this a too strong condition. + Actually we need only the fields referred in the + result set. And for some of them it makes sense to use + the values directly from sorted fields. */ *plength= 0; + /* - The following statement is added to avoid sorting in alter_table. - The fact is the filter 'field->query_id != thd->query_id' - doesn't work for alter table + The following statement is added to avoid sorting in alter_table. + The fact is the filter 'field->query_id != thd->query_id' + doesn't work for alter table */ - if (thd->lex->sql_command != SQLCOM_SELECT) + if (thd->lex->sql_command != SQLCOM_SELECT && + thd->lex->sql_command != SQLCOM_INSERT_SELECT) return 0; for (pfield= ptabfield; (field= *pfield) ; pfield++) { - if (field->query_id != thd->query_id) + if (field->query_id != query_id) continue; if (field->flags & BLOB_FLAG) return 0; diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 6ad385ae848..a5714769bc5 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -85,7 +85,6 @@ class ha_innobase: public handler ha_innobase(TABLE *table): handler(table), int_table_flags(HA_REC_NOT_IN_SEQ | HA_NULL_IN_KEY | - HA_FAST_KEY_READ | HA_CAN_INDEX_BLOBS | HA_CAN_SQL_HANDLER | HA_NOT_EXACT_COUNT | diff --git a/sql/handler.h b/sql/handler.h index 3751af29194..c9a7d17e6dc 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -47,14 +47,22 @@ #define HA_ADMIN_WRONG_CHECKSUM -8 /* Bits in table_flags() to show what database can do */ -#define HA_READ_RND_SAME (1 << 0) /* can switch index during the scan - with ::rnd_same() - not used yet. - see mi_rsame/heap_rsame/myrg_rsame */ + +/* + Can switch index during the scan with ::rnd_same() - not used yet. + see mi_rsame/heap_rsame/myrg_rsame +*/ +#define HA_READ_RND_SAME (1 << 0) #define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */ #define HA_REC_NOT_IN_SEQ (1 << 3) /* ha_info don't return recnumber; It returns a position to ha_r_rnd */ #define HA_CAN_GEOMETRY (1 << 4) -#define HA_FAST_KEY_READ (1 << 5) /* no need for a record cache in filesort */ +/* + Reading keys in random order is as fast as reading keys in sort order + (Used in records.cc to decide if we should use a record cache and by + filesort to decide if we should sort key + data or key + pointer-to-row +*/ +#define HA_FAST_KEY_READ (1 << 5) #define HA_NULL_IN_KEY (1 << 7) /* One can have keys with NULL */ #define HA_DUPP_POS (1 << 8) /* ha_position() gives dup row */ #define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */ @@ -62,9 +70,11 @@ #define HA_AUTO_PART_KEY (1 << 11) /* auto-increment in multi-part key */ #define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */ #define HA_NOT_EXACT_COUNT (1 << 13) -#define HA_CAN_INSERT_DELAYED (1 << 14) /* only handlers with table-level locks - need no special code to support - INSERT DELAYED */ +/* + INSERT_DELAYED only works with handlers that uses MySQL internal table + level locks +*/ +#define HA_CAN_INSERT_DELAYED (1 << 14) #define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15) #define HA_NOT_DELETE_WITH_CACHE (1 << 18) #define HA_NO_PREFIX_CHAR_KEYS (1 << 20) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 1b1da6772af..a854f8c45d3 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -116,7 +116,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; The following parameters is to decide when to use an extra cache to optimise seeks when reading a big table in sorted order */ -#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (16L*1024*1024) +#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (10L*1024*1024) #define MIN_ROWS_TO_USE_TABLE_CACHE 100 #define MIN_ROWS_TO_USE_BULK_INSERT 100 diff --git a/sql/records.cc b/sql/records.cc index b71bcf70865..9b05dc3e291 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -89,7 +89,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, (ulonglong) MIN_FILE_LENGTH_TO_USE_ROW_CACHE && info->io_cache->end_of_file/info->ref_length * table->s->reclength > (my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE && - !table->s->blob_fields) + !table->s->blob_fields && + info->ref_length <= MAX_REFLENGTH) { if (! init_rr_cache(thd, info)) { @@ -348,7 +349,8 @@ static int init_rr_cache(THD *thd, READ_RECORD *info) MYF(0)))) DBUG_RETURN(1); #ifdef HAVE_purify - bzero(info->cache,rec_cache_size); // Avoid warnings in qsort + // Avoid warnings in qsort + bzero(info->cache,rec_cache_size+info->cache_records* info->struct_length+1); #endif DBUG_PRINT("info",("Allocated buffert for %d records",info->cache_records)); info->read_positions=info->cache+rec_cache_size; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index baf2ef09d2b..cbae2848094 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8026,6 +8026,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, */ (*argp)->maybe_null=1; } + new_field->query_id= thd->query_id; } } } @@ -8072,6 +8073,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, group_null_items++; new_field->flags|= GROUP_FLAG; } + new_field->query_id= thd->query_id; *(reg_field++) =new_field; } if (!--hidden_field_count) From 43d926029f31206c01e0faea0ac3ccbd8d1f05c5 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Thu, 7 Apr 2005 09:51:56 -0700 Subject: [PATCH 65/83] Add cp932 and eucjpms character sets to Windows build. (Bug #9479) --- VC++Files/client/mysqlclient.dsp | 8 ++++++++ VC++Files/client/mysqlclient_ia64.dsp | 8 ++++++++ VC++Files/libmysql/libmysql.dsp | 8 ++++++++ VC++Files/libmysql/libmysql_ia64.dsp | 8 ++++++++ VC++Files/strings/strings.dsp | 8 ++++++++ VC++Files/strings/strings_ia64.dsp | 8 ++++++++ include/config-win.h | 2 ++ 7 files changed, 50 insertions(+) diff --git a/VC++Files/client/mysqlclient.dsp b/VC++Files/client/mysqlclient.dsp index 75008858e55..157c576b187 100644 --- a/VC++Files/client/mysqlclient.dsp +++ b/VC++Files/client/mysqlclient.dsp @@ -147,6 +147,10 @@ SOURCE="..\strings\ctype-bin.c" # End Source File # Begin Source File +SOURCE="..\strings\ctype-cp932.c" +# End Source File +# Begin Source File + SOURCE="..\strings\ctype-czech.c" # End Source File # Begin Source File @@ -155,6 +159,10 @@ SOURCE="..\strings\ctype-euc_kr.c" # End Source File # Begin Source File +SOURCE="..\strings\ctype-eucjpms.c" +# End Source File +# Begin Source File + SOURCE="..\strings\ctype-extra.c" # End Source File # Begin Source File diff --git a/VC++Files/client/mysqlclient_ia64.dsp b/VC++Files/client/mysqlclient_ia64.dsp index e91245c12b2..a69c5cf58af 100644 --- a/VC++Files/client/mysqlclient_ia64.dsp +++ b/VC++Files/client/mysqlclient_ia64.dsp @@ -147,6 +147,10 @@ SOURCE="..\strings\ctype-bin.c" # End Source File # Begin Source File +SOURCE="..\strings\ctype-cp932.c" +# End Source File +# Begin Source File + SOURCE="..\strings\ctype-czech.c" # End Source File # Begin Source File @@ -155,6 +159,10 @@ SOURCE="..\strings\ctype-euc_kr.c" # End Source File # Begin Source File +SOURCE="..\strings\ctype-eucjpms.c" +# End Source File +# Begin Source File + SOURCE="..\strings\ctype-extra.c" # End Source File # Begin Source File diff --git a/VC++Files/libmysql/libmysql.dsp b/VC++Files/libmysql/libmysql.dsp index ce81a3b7435..34c479c73b4 100644 --- a/VC++Files/libmysql/libmysql.dsp +++ b/VC++Files/libmysql/libmysql.dsp @@ -139,6 +139,10 @@ SOURCE="..\strings\ctype-bin.c" # End Source File # Begin Source File +SOURCE="..\strings\ctype-cp932.c" +# End Source File +# Begin Source File + SOURCE="..\strings\ctype-czech.c" # End Source File # Begin Source File @@ -147,6 +151,10 @@ SOURCE="..\strings\ctype-euc_kr.c" # End Source File # Begin Source File +SOURCE="..\strings\ctype-eucjpms.c" +# End Source File +# Begin Source File + SOURCE="..\strings\ctype-extra.c" # End Source File # Begin Source File diff --git a/VC++Files/libmysql/libmysql_ia64.dsp b/VC++Files/libmysql/libmysql_ia64.dsp index 4c4776dfc2f..fa851cb81c5 100644 --- a/VC++Files/libmysql/libmysql_ia64.dsp +++ b/VC++Files/libmysql/libmysql_ia64.dsp @@ -138,6 +138,10 @@ SOURCE="..\strings\ctype-bin.c" # End Source File # Begin Source File +SOURCE="..\strings\ctype-cp932.c" +# End Source File +# Begin Source File + SOURCE="..\strings\ctype-czech.c" # End Source File # Begin Source File @@ -146,6 +150,10 @@ SOURCE="..\strings\ctype-euc_kr.c" # End Source File # Begin Source File +SOURCE="..\strings\ctype-eucjpms.c" +# End Source File +# Begin Source File + SOURCE="..\strings\ctype-extra.c" # End Source File # Begin Source File diff --git a/VC++Files/strings/strings.dsp b/VC++Files/strings/strings.dsp index 340617344f2..320cdaf2132 100644 --- a/VC++Files/strings/strings.dsp +++ b/VC++Files/strings/strings.dsp @@ -113,10 +113,18 @@ SOURCE=".\ctype-bin.c" # End Source File # Begin Source File +SOURCE=".\ctype-cp932.c" +# End Source File +# Begin Source File + SOURCE=".\ctype-czech.c" # End Source File # Begin Source File +SOURCE=".\ctype-eucjpms.c" +# End Source File +# Begin Source File + SOURCE=".\ctype-euc_kr.c" # End Source File # Begin Source File diff --git a/VC++Files/strings/strings_ia64.dsp b/VC++Files/strings/strings_ia64.dsp index 6449b2b1355..a34a238dfdc 100644 --- a/VC++Files/strings/strings_ia64.dsp +++ b/VC++Files/strings/strings_ia64.dsp @@ -112,6 +112,10 @@ SOURCE=".\ctype-bin.c" # End Source File # Begin Source File +SOURCE=".\ctype-cp932.c" +# End Source File +# Begin Source File + SOURCE=".\ctype-czech.c" # End Source File # Begin Source File @@ -120,6 +124,10 @@ SOURCE=".\ctype-euc_kr.c" # End Source File # Begin Source File +SOURCE=".\ctype-eucjpms.c" +# End Source File +# Begin Source File + SOURCE=".\ctype-extra.c" # End Source File # Begin Source File diff --git a/include/config-win.h b/include/config-win.h index df0530fbef3..bc392ce73d8 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -378,6 +378,7 @@ inline double ulonglong2double(ulonglong value) /* #undef HAVE_CHARSET_armscii8 */ /* #undef HAVE_CHARSET_ascii */ #define HAVE_CHARSET_big5 1 +#define HAVE_CHARSET_cp932 #define HAVE_CHARSET_cp1250 1 /* #undef HAVE_CHARSET_cp1251 */ /* #undef HAVE_CHARSET_cp1256 */ @@ -386,6 +387,7 @@ inline double ulonglong2double(ulonglong value) /* #undef HAVE_CHARSET_cp852 */ /* #undef HAVE_CHARSET_cp866 */ /* #undef HAVE_CHARSET_dec8 */ +#define HAVE_CHARSET_eucjpms 1 #define HAVE_CHARSET_euckr 1 #define HAVE_CHARSET_gb2312 1 #define HAVE_CHARSET_gbk 1 From 8327593bfd9fd7ad7161f2a0422e6091169ad422 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Thu, 7 Apr 2005 19:48:00 +0200 Subject: [PATCH 66/83] Merge --- mysql-test/r/ndb_basic.result | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index e1aa045d16e..e10d7e5a095 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -607,3 +607,33 @@ primary key (a)) engine=ndb max_rows=1; drop table t1; +create table t1 +(counter int(64) NOT NULL auto_increment, +datavalue char(40) default 'XXXX', +primary key (counter) +) ENGINE=ndbcluster; +insert into t1 (datavalue) values ('newval'); +insert into t1 (datavalue) values ('newval'); +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +3 newval +4 newval +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +3 newval +4 newval +35 newval +36 newval +37 newval +38 newval +drop table t1; From b716302860f5f6b97a2b2e2105c0b794caf8c487 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Thu, 7 Apr 2005 20:08:01 +0200 Subject: [PATCH 67/83] Fix for Bug #9675 Auto-increment not working with INSERT..SELECT and NDB storage, post review fix --- sql/ha_ndbcluster.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 31b16d58b62..4e1439bc680 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3933,7 +3933,10 @@ longlong ha_ndbcluster::get_auto_increment() DBUG_ENTER("get_auto_increment"); DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); Ndb *ndb= get_ndb(); - + + if (m_rows_inserted > m_rows_to_insert) + /* We guessed too low */ + m_rows_to_insert+= m_autoincrement_prefetch; int cache_size= (m_rows_to_insert - m_rows_inserted < m_autoincrement_prefetch) ? m_rows_to_insert - m_rows_inserted From 12b62521457490c28d79882dd674ac8c4d2daa68 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Thu, 7 Apr 2005 20:17:37 +0200 Subject: [PATCH 68/83] BUG#6762 ALTER TABLE gives weird results and error message - Removed hardcoded error message from 4.1 --- include/my_base.h | 4 +++- mysql-test/t/ndb_alter_table.test | 2 +- sql/ha_ndbcluster.cc | 13 +++---------- sql/handler.cc | 4 ++++ sql/share/errmsg.txt | 3 +++ 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index 1713a07f6ec..25fa683744e 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -312,7 +312,9 @@ enum ha_base_keytype { #define HA_ERR_TABLE_EXIST 156 /* The table existed in storage engine */ #define HA_ERR_NO_CONNECTION 157 /* Could not connect to storage engine */ #define HA_ERR_NULL_IN_SPATIAL 158 /* NULLs are not supported in spatial index */ -#define HA_ERR_LAST 158 /*Copy last error nr.*/ +#define HA_ERR_TABLE_DEF_CHANGED 159 /* The table changed in storage engine */ + +#define HA_ERR_LAST 159 /*Copy last error nr.*/ /* Add error numbers before HA_ERR_LAST and change it accordingly. */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test index 6f0e51b7a4d..18c7ff47b18 100644 --- a/mysql-test/t/ndb_alter_table.test +++ b/mysql-test/t/ndb_alter_table.test @@ -147,7 +147,7 @@ select * from t1 where b = 'two'; connection server1; alter table t1 drop index c; connection server2; ---error 1105 +--error 1412 select * from t1 where b = 'two'; select * from t1 where b = 'two'; connection server1; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 5848fc002e4..a60f8133d47 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -192,6 +192,8 @@ static const err_code_mapping err_map[]= { 827, HA_ERR_RECORD_FILE_FULL, 1 }, { 832, HA_ERR_RECORD_FILE_FULL, 1 }, + { 284, HA_ERR_TABLE_DEF_CHANGED, 0 }, + { 0, 1, 0 }, { -1, -1, 1 } @@ -470,16 +472,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans) if (err.code != 709) DBUG_RETURN(1); } - else - { - DBUG_PRINT("info", ("Table exist but must have changed")); - /* In 5.0, this should be replaced with a mapping to a mysql error */ - my_printf_error(ER_UNKNOWN_ERROR, - "Table definition has changed, "\ - "please retry transaction", - MYF(0)); - DBUG_RETURN(1); - } + DBUG_PRINT("info", ("Table exists but must have changed")); } break; default: diff --git a/sql/handler.cc b/sql/handler.cc index 7cd2fd303f0..f20ee0c4d77 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -304,6 +304,7 @@ static int ha_init_errors(void) SETMSG(HA_ERR_NO_SUCH_TABLE, "No such table: '%.64s'"); SETMSG(HA_ERR_TABLE_EXIST, ER(ER_TABLE_EXISTS_ERROR)); SETMSG(HA_ERR_NO_CONNECTION, "Could not connect to storage engine"); + SETMSG(HA_ERR_TABLE_DEF_CHANGED, ER(ER_TABLE_DEF_CHANGED)); /* Register the error messages for use with my_error(). */ return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST); @@ -1646,6 +1647,9 @@ void handler::print_error(int error, myf errflag) case HA_ERR_NO_REFERENCED_ROW: textno=ER_NO_REFERENCED_ROW; break; + case HA_ERR_TABLE_DEF_CHANGED: + textno=ER_TABLE_DEF_CHANGED; + break; case HA_ERR_NO_SUCH_TABLE: { /* diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 9a92f1f4f76..047c30f6cd0 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5336,3 +5336,6 @@ ER_CANT_CREATE_USER_WITH_GRANT 42000 eng "You are not allowed to create a user with GRANT" ER_WRONG_VALUE_FOR_TYPE eng "Incorrect %-.32s value: '%-.128s' for function %-.32s" +ER_TABLE_DEF_CHANGED + eng "Table definition has changed, please retry transaction" + From d936a80ceaa813170c94c681cd97fb80b28b901c Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Thu, 7 Apr 2005 21:04:18 +0200 Subject: [PATCH 69/83] - bumped up the version number in configure.in from 5.0.4 to 5.0.5 to indicate that engineering has branched off from the 4.1 tree to build the 5.0.4 release --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 01f669a0d1b..e98d032abc6 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ AC_PREREQ(2.50)dnl Minimum Autoconf version required. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # Don't forget to also update the NDB lines below. -AM_INIT_AUTOMAKE(mysql, 5.0.4-beta) +AM_INIT_AUTOMAKE(mysql, 5.0.5-beta) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From eae3f5ba1d866ef38e396f652cb5f0d50f9949ed Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 8 Apr 2005 09:23:10 +0500 Subject: [PATCH 70/83] Test result fixed --- mysql-test/r/cast.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index 79d903737bf..feefd47c611 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -94,7 +94,7 @@ select 10.0+cast('a' as decimal); 10.0+cast('a' as decimal) 10.00 Warnings: -Error 1366 Incorrect decimal value: '' for column '' at row -1 +Warning 1292 Truncated incorrect DECIMAL value: 'a' select 10E+0+'a'; 10E+0+'a' 10 From 813cc0eaf0ef9d89782ba35582cc859f85cd9bf7 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Fri, 8 Apr 2005 11:38:40 +0200 Subject: [PATCH 71/83] Added more tests for auto_increment --- mysql-test/r/ndb_basic.result | 42 ++++++++++++++++++++++++++++++----- mysql-test/t/ndb_basic.test | 2 ++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 12f9c3742e5..3712fa2b5ca 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -619,12 +619,6 @@ counter datavalue 1 newval 2 newval insert into t1 (datavalue) select datavalue from t1 where counter < 100; -select * from t1 order by counter; -counter datavalue -1 newval -2 newval -3 newval -4 newval insert into t1 (datavalue) select datavalue from t1 where counter < 100; select * from t1 order by counter; counter datavalue @@ -632,8 +626,44 @@ counter datavalue 2 newval 3 newval 4 newval +5 newval +6 newval +7 newval +8 newval +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +3 newval +4 newval +5 newval +6 newval +7 newval +8 newval 35 newval 36 newval 37 newval 38 newval +39 newval +40 newval +41 newval +42 newval +43 newval +44 newval +45 newval +46 newval +47 newval +48 newval +49 newval +50 newval +51 newval +52 newval +53 newval +54 newval +55 newval +56 newval +57 newval +58 newval drop table t1; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index 35e1ddc5ebf..66300f61fc3 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -596,9 +596,11 @@ insert into t1 (datavalue) values ('newval'); insert into t1 (datavalue) values ('newval'); select * from t1 order by counter; insert into t1 (datavalue) select datavalue from t1 where counter < 100; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; select * from t1 order by counter; connection con2; insert into t1 (datavalue) select datavalue from t1 where counter < 100; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; select * from t1 order by counter; drop table t1; From 20a82a1a6a88a84cddeecb475c1432dbf589ea29 Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Fri, 8 Apr 2005 12:34:52 +0200 Subject: [PATCH 72/83] Fixed broken auto_increment --- mysql-test/r/ndb_alter_table.result | 2 +- sql/ha_ndbcluster.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result index 54eaddfb0e9..6f4d84edef5 100644 --- a/mysql-test/r/ndb_alter_table.result +++ b/mysql-test/r/ndb_alter_table.result @@ -40,7 +40,7 @@ insert into t1 values (0,4,3,5,"PENDING",1,7),(NULL,4,3,5,"PENDING",1,7),(31,4,3,5,"PENDING",1,7), (7,4,3,5,"PENDING",1,7), (NULL,4,3,5,"PENDING",1,7), (100,4,3,5,"PENDING",1,7), (99,4,3,5,"PENDING",1,7), (8,4,3,5,"PENDING",1,7), (NULL,4,3,5,"PENDING",1,7); show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ndbcluster 10 Dynamic 9 96 # # 0 # 101 # # # latin1_swedish_ci NULL # +t1 ndbcluster 10 Dynamic 9 96 # # 0 # 102 # # # latin1_swedish_ci NULL # select * from t1 order by col1; col1 col2 col3 col4 col5 col6 to_be_deleted 0 4 3 5 PENDING 1 7 diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 495060eb994..1039eea99cd 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1938,8 +1938,12 @@ int ha_ndbcluster::write_row(byte *record) if (has_auto_increment) { + THD *thd= table->in_use; + m_skip_auto_increment= FALSE; update_auto_increment(); + /* Ensure that handler is always called for auto_increment values */ + thd->next_insert_id= 0; m_skip_auto_increment= !auto_increment_column_changed; } From 6bd1bea723e77a98512c9d46e3170ed4477d790c Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Fri, 8 Apr 2005 13:56:48 +0200 Subject: [PATCH 73/83] Add missing parts for the "Cybozu" custom build, to avoid future manual patches. --- BUILD/compile-pentium-cybozu | 9 +++++++++ configure.in | 27 +++++++++++++++++---------- mysys/charset-def.c | 4 ++-- strings/ctype-utf8.c | 2 +- 4 files changed, 29 insertions(+), 13 deletions(-) create mode 100755 BUILD/compile-pentium-cybozu diff --git a/BUILD/compile-pentium-cybozu b/BUILD/compile-pentium-cybozu new file mode 100755 index 00000000000..841635985a1 --- /dev/null +++ b/BUILD/compile-pentium-cybozu @@ -0,0 +1,9 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +extra_flags="$pentium_cflags $fast_cflags -g" +extra_configs="$pentium_configs --with-charset=utf8 --with-collation=utf8_general_cs" + +. "$path/FINISH.sh" diff --git a/configure.in b/configure.in index 03b0ed9be29..c4bd95b9a24 100644 --- a/configure.in +++ b/configure.in @@ -2770,16 +2770,23 @@ case $default_charset in ;; utf8) default_charset_default_collation="utf8_general_ci" - define(UTFC1, utf8_general_ci utf8_bin) - define(UTFC2, utf8_czech_ci utf8_danish_ci) - define(UTFC3, utf8_estonian_ci utf8_icelandic_ci) - define(UTFC4, utf8_latvian_ci utf8_lithuanian_ci) - define(UTFC5, utf8_persian_ci utf8_polish_ci utf8_romanian_ci) - define(UTFC6, utf8_slovak_ci utf8_slovenian_ci) - define(UTFC7, utf8_spanish2_ci utf8_spanish_ci) - define(UTFC8, utf8_swedish_ci utf8_turkish_ci) - define(UTFC9, utf8_unicode_ci) - UTFC="UTFC1 UTFC2 UTFC3 UTFC4 UTFC5 UTFC6 UTFC7 UTFC8 UTFC9" + if test "$default_collation" = "utf8_general_cs"; then + # For those who explicitly desire "utf8_general_cs", support it, + # and then also set the CPP switch enabling that code. + UTFC="utf8_general_cs" + AC_DEFINE([HAVE_UTF8_GENERAL_CS], [1], [certain Japanese customer]) + else + define(UTFC1, utf8_general_ci utf8_bin) + define(UTFC2, utf8_czech_ci utf8_danish_ci) + define(UTFC3, utf8_estonian_ci utf8_icelandic_ci) + define(UTFC4, utf8_latvian_ci utf8_lithuanian_ci) + define(UTFC5, utf8_persian_ci utf8_polish_ci utf8_romanian_ci) + define(UTFC6, utf8_slovak_ci utf8_slovenian_ci) + define(UTFC7, utf8_spanish2_ci utf8_spanish_ci) + define(UTFC8, utf8_swedish_ci utf8_turkish_ci) + define(UTFC9, utf8_unicode_ci) + UTFC="UTFC1 UTFC2 UTFC3 UTFC4 UTFC5 UTFC6 UTFC7 UTFC8 UTFC9" + fi default_charset_collations="$UTFC" ;; *) diff --git a/mysys/charset-def.c b/mysys/charset-def.c index c7fa0ffd8e0..d4f69a49a2c 100644 --- a/mysys/charset-def.c +++ b/mysys/charset-def.c @@ -62,7 +62,7 @@ extern CHARSET_INFO my_charset_utf8_slovak_uca_ci; extern CHARSET_INFO my_charset_utf8_spanish2_uca_ci; extern CHARSET_INFO my_charset_utf8_roman_uca_ci; extern CHARSET_INFO my_charset_utf8_persian_uca_ci; -#ifdef HAVE_CYBOZU_COLLATION +#ifdef HAVE_UTF8_GENERAL_CS extern CHARSET_INFO my_charset_utf8_general_cs; #endif #endif @@ -149,7 +149,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused))) #ifdef HAVE_CHARSET_utf8 add_compiled_collation(&my_charset_utf8_general_ci); add_compiled_collation(&my_charset_utf8_bin); -#ifdef HAVE_CYBOZU_COLLATION +#ifdef HAVE_UTF8_GENERAL_CS add_compiled_collation(&my_charset_utf8_general_cs); #endif #ifdef HAVE_UCA_COLLATIONS diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 83725878a50..230b44796e8 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2375,7 +2375,7 @@ CHARSET_INFO my_charset_utf8_bin= &my_collation_mb_bin_handler }; -#ifdef HAVE_CYBOZU_COLLATION +#ifdef HAVE_UTF8_GENERAL_CS /* * These functions bacically do the same as their original, except From 72d89cc253e2e25ed8eb1ae209d3d4ca5bad1248 Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Fri, 8 Apr 2005 14:15:37 +0200 Subject: [PATCH 74/83] bug#9749 - ndb test case for case 9749, ndb lock upgrade via NDBAPI --- ndb/test/ndbapi/testOperations.cpp | 93 ++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/ndb/test/ndbapi/testOperations.cpp b/ndb/test/ndbapi/testOperations.cpp index e254aff58dc..9f1d5ee1191 100644 --- a/ndb/test/ndbapi/testOperations.cpp +++ b/ndb/test/ndbapi/testOperations.cpp @@ -530,6 +530,74 @@ runOperations(NDBT_Context* ctx, NDBT_Step* step) return NDBT_OK; } +int +runLockUpgrade1(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoOperations hugoOps(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + if(hugoTrans.loadTable(pNdb, 1) != 0){ + g_err << "Load table failed" << endl; + return NDBT_FAILED; + } + + int result= NDBT_OK; + do + { + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 0, 1, NdbOperation::LM_Read) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + ctx->setProperty("READ_DONE", 1); + ctx->broadcast(); + ndbout_c("wait 2"); + ctx->getPropertyWait("READ_DONE", 2); + ndbout_c("wait 2 - done"); + ctx->setProperty("READ_DONE", 3); + ctx->broadcast(); + ndbout_c("before update"); + CHECK(hugoOps.pkUpdateRecord(pNdb, 0, 1, 2) == 0); + ndbout_c("wait update"); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb)); + } while(0); + + return result; +} + +int +runLockUpgrade2(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoOperations hugoOps(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + + int result= NDBT_OK; + do + { + CHECK(hugoOps.startTransaction(pNdb) == 0); + ndbout_c("wait 1"); + ctx->getPropertyWait("READ_DONE", 1); + ndbout_c("wait 1 - done"); + CHECK(hugoOps.pkReadRecord(pNdb, 0, 1, NdbOperation::LM_Read) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + ctx->setProperty("READ_DONE", 2); + ctx->broadcast(); + ndbout_c("wait 3"); + ctx->getPropertyWait("READ_DONE", 3); + ndbout_c("wait 3 - done"); + + NdbSleep_MilliSleep(200); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + } while(0); + + return NDBT_FAILED; +} + int main(int argc, const char** argv){ ndb_init(); @@ -538,6 +606,31 @@ main(int argc, const char** argv){ generate(tmp, 5); NDBT_TestSuite ts("testOperations"); + + { + BaseString name("bug_9749"); + NDBT_TestCaseImpl1 *pt = new NDBT_TestCaseImpl1(&ts, + name.c_str(), ""); + + pt->addInitializer(new NDBT_Initializer(pt, + "runClearTable", + runClearTable)); + + pt->addStep(new NDBT_ParallelStep(pt, + "thread1", + runLockUpgrade1)); + + + pt->addStep(new NDBT_ParallelStep(pt, + "thread2", + runLockUpgrade2)); + + pt->addFinalizer(new NDBT_Finalizer(pt, + "runClearTable", + runClearTable)); + ts.addTest(pt); + } + for(size_t i = 0; i Date: Fri, 8 Apr 2005 16:05:16 +0200 Subject: [PATCH 75/83] Fixed BUG#7299: Stored procedures: exception handler catches not-found conditions --- mysql-test/r/sp-error.result | 13 +++++++++++++ mysql-test/t/sp-error.test | 22 ++++++++++++++++++++++ sql/sp_rcontext.cc | 4 ++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index ff7d71b3384..42e45f67d33 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -513,4 +513,17 @@ call bug9566()| ERROR HY000: Table 'proc' was not locked with LOCK TABLES unlock tables| drop procedure bug9566| +drop procedure if exists bug7299| +create procedure bug7299() +begin +declare v int; +declare c cursor for select val from t1; +declare exit handler for sqlexception select 'Error!'; +open c; +fetch c into v; +end| +delete from t1| +call bug7299()| +ERROR 02000: No data to FETCH +drop procedure bug7299| drop table t1| diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 51776453730..90c776a8b88 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -720,6 +720,28 @@ unlock tables| drop procedure bug9566| +# +# BUG#7299: Stored procedures: exception handler catches not-found conditions +# +--disable_warnings +drop procedure if exists bug7299| +--enable_warnings +create procedure bug7299() +begin + declare v int; + declare c cursor for select val from t1; + declare exit handler for sqlexception select 'Error!'; + + open c; + fetch c into v; +end| + +delete from t1| +--error ER_SP_FETCH_NO_DATA +call bug7299()| +drop procedure bug7299| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 9b29c173856..e9271146cad 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -95,8 +95,8 @@ sp_rcontext::find_handler(uint sql_errno, found= i; break; case sp_cond_type_t::exception: - if ((sqlstate[0] != '0' || sqlstate[1] > '2' || - level == MYSQL_ERROR::WARN_LEVEL_ERROR) && + if ((sqlstate[0] != '0' || sqlstate[1] > '2') && + level == MYSQL_ERROR::WARN_LEVEL_ERROR && (found < 0 || m_handler[found].cond->type > sp_cond_type_t::state)) found= i; break; From 497f2684d8f61f4971ebcd28b1de5110dad51c7a Mon Sep 17 00:00:00 2001 From: "mskold@mysql.com" <> Date: Fri, 8 Apr 2005 16:49:14 +0200 Subject: [PATCH 76/83] Merge from fix of Bug #9675 Auto-increment not working with INSERT..SELECT and NDB storage --- mysql-test/r/ndb_alter_table.result | 2 +- mysql-test/r/ndb_basic.result | 60 +++++++++++++++++++++++++++++ mysql-test/t/ndb_basic.test | 27 +++++++++++++ sql/ha_ndbcluster.cc | 14 ++++++- 4 files changed, 101 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result index 9bc82e7a24a..d3a9289283e 100644 --- a/mysql-test/r/ndb_alter_table.result +++ b/mysql-test/r/ndb_alter_table.result @@ -40,7 +40,7 @@ insert into t1 values (0,4,3,5,"PENDING",1,7),(NULL,4,3,5,"PENDING",1,7),(31,4,3,5,"PENDING",1,7), (7,4,3,5,"PENDING",1,7), (NULL,4,3,5,"PENDING",1,7), (100,4,3,5,"PENDING",1,7), (99,4,3,5,"PENDING",1,7), (8,4,3,5,"PENDING",1,7), (NULL,4,3,5,"PENDING",1,7); show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 ndbcluster 10 Dynamic 9 96 # # 0 # 101 # # # latin1_swedish_ci NULL # +t1 ndbcluster 10 Dynamic 9 96 # # 0 # 102 # # # latin1_swedish_ci NULL # select * from t1 order by col1; col1 col2 col3 col4 col5 col6 to_be_deleted 0 4 3 5 PENDING 1 7 diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index e1aa045d16e..6383a636cad 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -607,3 +607,63 @@ primary key (a)) engine=ndb max_rows=1; drop table t1; +create table t1 +(counter int(64) NOT NULL auto_increment, +datavalue char(40) default 'XXXX', +primary key (counter) +) ENGINE=ndbcluster; +insert into t1 (datavalue) values ('newval'); +insert into t1 (datavalue) values ('newval'); +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +3 newval +4 newval +5 newval +6 newval +7 newval +8 newval +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; +counter datavalue +1 newval +2 newval +3 newval +4 newval +5 newval +6 newval +7 newval +8 newval +35 newval +36 newval +37 newval +38 newval +39 newval +40 newval +41 newval +42 newval +43 newval +44 newval +45 newval +46 newval +47 newval +48 newval +49 newval +50 newval +51 newval +52 newval +53 newval +54 newval +55 newval +56 newval +57 newval +58 newval +drop table t1; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index a6064f30556..5dfc2d5ec58 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -577,3 +577,30 @@ create table t1 engine=ndb max_rows=1; drop table t1; + +# +# Test auto_increment +# + +connect (con1,localhost,,,test); +connect (con2,localhost,,,test); + +create table t1 + (counter int(64) NOT NULL auto_increment, + datavalue char(40) default 'XXXX', + primary key (counter) + ) ENGINE=ndbcluster; + +connection con1; +insert into t1 (datavalue) values ('newval'); +insert into t1 (datavalue) values ('newval'); +select * from t1 order by counter; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; +connection con2; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +insert into t1 (datavalue) select datavalue from t1 where counter < 100; +select * from t1 order by counter; + +drop table t1; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 0668c3db7a8..6d843605e2f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1919,8 +1919,12 @@ int ha_ndbcluster::write_row(byte *record) if (has_auto_increment) { + THD *thd= table->in_use; + m_skip_auto_increment= FALSE; update_auto_increment(); + /* Ensure that handler is always called for auto_increment values */ + thd->next_insert_id= 0; m_skip_auto_increment= !auto_increment_column_changed; } @@ -2970,7 +2974,11 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows) DBUG_PRINT("enter", ("rows: %d", (int)rows)); m_rows_inserted= 0; - m_rows_to_insert= rows; + if (rows == 0) + /* We don't know how many will be inserted, guess */ + m_rows_to_insert= m_autoincrement_prefetch; + else + m_rows_to_insert= rows; /* Calculate how many rows that should be inserted @@ -4080,6 +4088,10 @@ ulonglong ha_ndbcluster::get_auto_increment() DBUG_ENTER("get_auto_increment"); DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); Ndb *ndb= get_ndb(); + + if (m_rows_inserted > m_rows_to_insert) + /* We guessed too low */ + m_rows_to_insert+= m_autoincrement_prefetch; cache_size= (m_rows_to_insert - m_rows_inserted < m_autoincrement_prefetch) ? m_rows_to_insert - m_rows_inserted From ce2e40ac1972dc883cb7480880613d45b11c669d Mon Sep 17 00:00:00 2001 From: "pem@mysql.comhem.se" <> Date: Fri, 8 Apr 2005 17:31:37 +0200 Subject: [PATCH 77/83] Fixed BUG#6900: Stored procedure inner handler ignored and BUG#9074: STORED PROC: The scope of every handler declared is not properly applied --- mysql-test/r/sp.result | 65 +++++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 83 ++++++++++++++++++++++++++++++++++++++++++ sql/sp_rcontext.cc | 8 ++-- 3 files changed, 152 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index daad032b854..36a4331c9be 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -2779,4 +2779,69 @@ a 3.2000 drop procedure bug8937| delete from t1| +drop procedure if exists bug6900| +drop procedure if exists bug9074| +drop procedure if exists bug6900_9074| +drop table if exists t3| +create table t3 (w char unique, x char)| +insert into t3 values ('a', 'b')| +create procedure bug6900() +begin +declare exit handler for sqlexception select '1'; +begin +declare exit handler for sqlexception select '2'; +insert into t3 values ('x', 'y', 'z'); +end; +end| +create procedure bug9074() +begin +declare x1, x2, x3, x4, x5, x6 int default 0; +begin +declare continue handler for sqlstate '23000' set x5 = 1; +insert into t3 values ('a', 'b'); +set x6 = 1; +end; +begin1_label: +begin +declare continue handler for sqlstate '23000' set x1 = 1; +insert into t3 values ('a', 'b'); +set x2 = 1; +begin2_label: +begin +declare exit handler for sqlstate '23000' set x3 = 1; +set x4= 1; +insert into t3 values ('a','b'); +set x4= 0; +end begin2_label; +end begin1_label; +select x1, x2, x3, x4, x5, x6; +end| +create procedure bug6900_9074(z int) +begin +declare exit handler for sqlstate '23000' select '23000'; +begin +declare exit handler for sqlexception select 'sqlexception'; +if z = 1 then +insert into t3 values ('a', 'b'); +else +insert into t3 values ('x', 'y', 'z'); +end if; +end; +end| +call bug6900()| +2 +2 +call bug9074()| +x1 x2 x3 x4 x5 x6 +1 1 1 1 1 1 +call bug6900_9074(0)| +sqlexception +sqlexception +call bug6900_9074(1)| +23000 +23000 +drop procedure bug6900| +drop procedure bug9074| +drop procedure bug6900_9074| +drop table t3| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index a741a4af7d8..69c7544ee7c 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3398,6 +3398,89 @@ drop procedure bug8937| delete from t1| +# +# BUG#6900: Stored procedure inner handler ignored +# BUG#9074: STORED PROC: The scope of every handler declared is not +# properly applied +# +--disable_warnings +drop procedure if exists bug6900| +drop procedure if exists bug9074| +drop procedure if exists bug6900_9074| +drop table if exists t3| +--enable_warnings + +create table t3 (w char unique, x char)| +insert into t3 values ('a', 'b')| + +create procedure bug6900() +begin + declare exit handler for sqlexception select '1'; + + begin + declare exit handler for sqlexception select '2'; + + insert into t3 values ('x', 'y', 'z'); + end; +end| + +create procedure bug9074() +begin + declare x1, x2, x3, x4, x5, x6 int default 0; + + begin + declare continue handler for sqlstate '23000' set x5 = 1; + + insert into t3 values ('a', 'b'); + set x6 = 1; + end; + + begin1_label: + begin + declare continue handler for sqlstate '23000' set x1 = 1; + + insert into t3 values ('a', 'b'); + set x2 = 1; + + begin2_label: + begin + declare exit handler for sqlstate '23000' set x3 = 1; + + set x4= 1; + insert into t3 values ('a','b'); + set x4= 0; + end begin2_label; + end begin1_label; + + select x1, x2, x3, x4, x5, x6; +end| + +create procedure bug6900_9074(z int) +begin + declare exit handler for sqlstate '23000' select '23000'; + + begin + declare exit handler for sqlexception select 'sqlexception'; + + if z = 1 then + insert into t3 values ('a', 'b'); + else + insert into t3 values ('x', 'y', 'z'); + end if; + end; +end| + +call bug6900()| +call bug9074()| +call bug6900_9074(0)| +call bug6900_9074(1)| + +drop procedure bug6900| +drop procedure bug9074| +drop procedure bug6900_9074| +drop table t3| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index e9271146cad..d98cdfdd226 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -80,24 +80,24 @@ sp_rcontext::find_handler(uint sql_errno, break; case sp_cond_type_t::state: if (strcmp(sqlstate, cond->sqlstate) == 0 && - (found < 0 || m_handler[found].cond->type > sp_cond_type_t::number)) + (found < 0 || m_handler[found].cond->type > sp_cond_type_t::state)) found= i; break; case sp_cond_type_t::warning: if ((sqlstate[0] == '0' && sqlstate[1] == '1' || level == MYSQL_ERROR::WARN_LEVEL_WARN) && - (found < 0 || m_handler[found].cond->type > sp_cond_type_t::state)) + found < 0) found= i; break; case sp_cond_type_t::notfound: if (sqlstate[0] == '0' && sqlstate[1] == '2' && - (found < 0 || m_handler[found].cond->type > sp_cond_type_t::state)) + found < 0) found= i; break; case sp_cond_type_t::exception: if ((sqlstate[0] != '0' || sqlstate[1] > '2') && level == MYSQL_ERROR::WARN_LEVEL_ERROR && - (found < 0 || m_handler[found].cond->type > sp_cond_type_t::state)) + found < 0) found= i; break; } From 2038ced40cb61e4e457f5b5f6cb6ff1fd526399b Mon Sep 17 00:00:00 2001 From: "pem@mysql.comhem.se" <> Date: Fri, 8 Apr 2005 19:58:04 +0200 Subject: [PATCH 78/83] Fixed BUG#9073: Able to declare two handlers for same condition in same scope --- mysql-test/r/sp-error.result | 41 +++++++++++++++++++++++++++++ mysql-test/t/sp-error.test | 50 ++++++++++++++++++++++++++++++++++++ sql/share/errmsg.txt | 3 ++- sql/sp_pcontext.cc | 37 ++++++++++++++++++++++++++ sql/sp_pcontext.h | 10 ++++++++ sql/sql_yacc.yy | 36 +++++++++++++++++++++----- 6 files changed, 170 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 42e45f67d33..b9d33bbe606 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -526,4 +526,45 @@ delete from t1| call bug7299()| ERROR 02000: No data to FETCH drop procedure bug7299| +create procedure bug9073() +begin +declare continue handler for sqlexception select 1; +declare continue handler for sqlexception select 2; +end| +ERROR 42000: Duplicate handler declared in the same block +create procedure bug9073() +begin +declare condname1 condition for 1234; +declare continue handler for condname1 select 1; +declare exit handler for condname1 select 2; +end| +ERROR 42000: Duplicate handler declared in the same block +create procedure bug9073() +begin +declare condname1 condition for sqlstate '42000'; +declare condname2 condition for sqlstate '42000'; +declare exit handler for condname1 select 1; +declare continue handler for condname2 select 2; +end| +ERROR 42000: Duplicate handler declared in the same block +create procedure bug9073() +begin +declare condname1 condition for sqlstate '42000'; +declare exit handler for condname1 select 1; +declare exit handler for sqlstate '42000' select 2; +end| +ERROR 42000: Duplicate handler declared in the same block +drop procedure if exists bug9073| +create procedure bug9073() +begin +declare condname1 condition for sqlstate '42000'; +declare continue handler for condname1 select 1; +begin +declare exit handler for sqlstate '42000' select 2; +begin +declare continue handler for sqlstate '42000' select 3; +end; +end; +end| +drop procedure bug9073| drop table t1| diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 90c776a8b88..a02d2ff6733 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -742,6 +742,56 @@ call bug7299()| drop procedure bug7299| +# +# BUG#9073: Able to declare two handlers for same condition in same scope +# +--error ER_SP_DUP_HANDLER +create procedure bug9073() +begin + declare continue handler for sqlexception select 1; + declare continue handler for sqlexception select 2; +end| +--error ER_SP_DUP_HANDLER +create procedure bug9073() +begin + declare condname1 condition for 1234; + declare continue handler for condname1 select 1; + declare exit handler for condname1 select 2; +end| +--error ER_SP_DUP_HANDLER +create procedure bug9073() +begin + declare condname1 condition for sqlstate '42000'; + declare condname2 condition for sqlstate '42000'; + declare exit handler for condname1 select 1; + declare continue handler for condname2 select 2; +end| +--error ER_SP_DUP_HANDLER +create procedure bug9073() +begin + declare condname1 condition for sqlstate '42000'; + declare exit handler for condname1 select 1; + declare exit handler for sqlstate '42000' select 2; +end| + +# This should still work. +--disable_warnings +drop procedure if exists bug9073| +--enable_warnings +create procedure bug9073() +begin + declare condname1 condition for sqlstate '42000'; + declare continue handler for condname1 select 1; + begin + declare exit handler for sqlstate '42000' select 2; + begin + declare continue handler for sqlstate '42000' select 3; + end; + end; +end| +drop procedure bug9073| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 2ef2555753d..95fb1736741 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5338,4 +5338,5 @@ ER_WRONG_VALUE_FOR_TYPE eng "Incorrect %-.32s value: '%-.128s' for function %-.32s" ER_TABLE_DEF_CHANGED eng "Table definition has changed, please retry transaction" - +ER_SP_DUP_HANDLER 42000 + eng "Duplicate handler declared in the same block" diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index 15d3f87ff29..26f576233f3 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -57,6 +57,7 @@ sp_pcontext::sp_pcontext(sp_pcontext *prev) VOID(my_init_dynamic_array(&m_pvar, sizeof(sp_pvar_t *), 16, 8)); VOID(my_init_dynamic_array(&m_cond, sizeof(sp_cond_type_t *), 16, 8)); VOID(my_init_dynamic_array(&m_cursor, sizeof(LEX_STRING), 16, 8)); + VOID(my_init_dynamic_array(&m_handler, sizeof(sp_cond_type_t *), 16, 8)); m_label.empty(); m_children.empty(); if (!prev) @@ -82,6 +83,7 @@ sp_pcontext::destroy() delete_dynamic(&m_pvar); delete_dynamic(&m_cond); delete_dynamic(&m_cursor); + delete_dynamic(&m_handler); } sp_pcontext * @@ -258,6 +260,41 @@ sp_pcontext::find_cond(LEX_STRING *name, my_bool scoped) return NULL; } +/* + * This only searches the current context, for error checking of + * duplicates. + * Returns TRUE if found. + */ +bool +sp_pcontext::find_handler(sp_cond_type_t *cond) +{ + uint i= m_handler.elements; + + while (i--) + { + sp_cond_type_t *p; + + get_dynamic(&m_handler, (gptr)&p, i); + if (cond->type == p->type) + { + switch (p->type) + { + case sp_cond_type_t::number: + if (cond->mysqlerr == p->mysqlerr) + return TRUE; + break; + case sp_cond_type_t::state: + if (strcmp(cond->sqlstate, p->sqlstate) == 0) + return TRUE; + break; + default: + return TRUE; + } + } + } + return FALSE; +} + void sp_pcontext::push_cursor(LEX_STRING *name) { diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 42d8140b78c..dbce191975a 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -241,6 +241,15 @@ class sp_pcontext : public Sql_alloc m_handlers+= 1; } + inline void + push_handler(sp_cond_type_t *cond) + { + insert_dynamic(&m_handler, (gptr)&cond); + } + + bool + find_handler(sp_cond_type *cond); + inline uint max_handlers() { @@ -293,6 +302,7 @@ private: DYNAMIC_ARRAY m_pvar; // Parameters/variables DYNAMIC_ARRAY m_cond; // Conditions DYNAMIC_ARRAY m_cursor; // Cursors + DYNAMIC_ARRAY m_handler; // Handlers, for checking of duplicates List m_label; // The label list diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9266ab69790..9ff7f4449b2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1774,19 +1774,43 @@ sp_hcond_list: { LEX *lex= Lex; sp_head *sp= lex->sphead; - sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction(); + sp_pcontext *ctx= lex->spcont; - i->add_condition($1); - $$= 1; + if (ctx->find_handler($1)) + { + my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0)); + YYABORT; + } + else + { + sp_instr_hpush_jump *i= + (sp_instr_hpush_jump *)sp->last_instruction(); + + i->add_condition($1); + ctx->push_handler($1); + $$= 1; + } } | sp_hcond_list ',' sp_hcond { LEX *lex= Lex; sp_head *sp= lex->sphead; - sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction(); + sp_pcontext *ctx= lex->spcont; - i->add_condition($3); - $$= $1 + 1; + if (ctx->find_handler($3)) + { + my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0)); + YYABORT; + } + else + { + sp_instr_hpush_jump *i= + (sp_instr_hpush_jump *)sp->last_instruction(); + + i->add_condition($3); + ctx->push_handler($3); + $$= $1 + 1; + } } ; From 0998ec4264c802b9ff8b0237bb7790923523e5d6 Mon Sep 17 00:00:00 2001 From: "acurtis@xiphis.org" <> Date: Sat, 9 Apr 2005 00:21:51 +0100 Subject: [PATCH 79/83] Fix typos in Bug#6776 --- sql/sql_udf.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 19df1a85565..661bf6e8197 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -526,11 +526,11 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) tables.real_name= tables.alias= (char*) "func"; if (!(table = open_ltable(thd,&tables,TL_WRITE))) goto err; - table->field[0]->store(udf_name.str, udf_name.length, system_charset_info); + table->field[0]->store(udf_name->str, udf_name->length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (!table->file->index_read_idx(table->record[0], 0, (byte*) table->field[0]->ptr, - table->key_info[0].key_length + table->key_info[0].key_length, HA_READ_KEY_EXACT)) { int error; From b47f7902d35b02939adee9852c1607d228390fff Mon Sep 17 00:00:00 2001 From: "jani@a193-229-222-105.elisa-laajakaista.fi" <> Date: Sat, 9 Apr 2005 18:37:32 +0300 Subject: [PATCH 80/83] New versions of mail_to_db.pl and pmail.pl. Added email threading capabilities to both programs. --- tests/mail_to_db.pl | 54 ++++++-- tests/pmail.pl | 309 +++++++++++++++++++++++++++++++------------- 2 files changed, 258 insertions(+), 105 deletions(-) diff --git a/tests/mail_to_db.pl b/tests/mail_to_db.pl index dc40fb3ede6..5ceda392313 100755 --- a/tests/mail_to_db.pl +++ b/tests/mail_to_db.pl @@ -17,7 +17,7 @@ use DBI; use Getopt::Long; $| = 1; -$VER = "2.6"; +$VER = "3.0"; $opt_help = 0; $opt_version = 0; @@ -26,7 +26,6 @@ $opt_host = undef(); $opt_port = undef(); $opt_socket = undef(); $opt_db = "mail"; -$opt_table = "mails"; $opt_user = undef(); $opt_password = undef(); $opt_max_mail_size = 65536; @@ -97,7 +96,7 @@ sub main print "the my.cnf file. This command is available from the latest MySQL\n"; print "distribution.\n"; } - GetOptions("help","version","host=s","port=i","socket=s","db=s","table=s", + GetOptions("help","version","host=s","port=i","socket=s","db=s", "user=s","password=s","max_mail_size=i","create","test", "no_path","debug","stop_on_error","stdin") || die "Wrong option! See $progname --help\n"; @@ -123,7 +122,6 @@ sub main || die "Couldn't connect: $DBI::errstr\n"; die "You must specify the database; use --db=" if (!defined($opt_db)); - die "You must specify the table; use --table=" if (!defined($opt_table)); create_table($dbh) if ($opt_create); @@ -218,9 +216,9 @@ sub main print "Total number of mails:\t\t\t\t"; print $mail_inserted + $ignored; print " (OK: "; - print sprintf("%.1f", (($mail_inserted / ($mail_inserted+$ignored)) * 100)); + print sprintf("%.1f", ($mail_inserted + $ignored) ? (($mail_inserted / ($mail_inserted+$ignored)) * 100) : 0.0); print "% Ignored: "; - print sprintf("%.1f", (($ignored / ($mail_inserted + $ignored)) * 100)); + print sprintf("%.1f", ($mail_inserted + $ignored) ? (($ignored / ($mail_inserted + $ignored)) * 100) : 0); print "%)\n"; print "################################ End Report ##################################\n"; exit(0); @@ -232,13 +230,15 @@ sub main sub create_table { - my ($dbh) = @_; + my ($dbh)= @_; my ($sth, $query); - $query = <)\s*/$1/; + $values{$type} = $1; + } + elsif (/^In-Reply-To:\s*(.*)/i) + { + $type = "in_reply_to"; + s/^\s*(<.*>)\s*/$1/; + $values{$type} = $1; + } elsif (/^Date: (.*)/i) { date_parser($1, \%values, $file_name); $type = "rubbish"; } - elsif (/^[\w\W-]+:\s/) + # Catch those fields that we don't or can't handle (yet) + elsif (/^[\w\W-]+:/) { - $type = "rubbish"; + $type = "rubbish"; } elsif ($_ eq "") { @@ -319,6 +334,10 @@ sub process_mail_file else { s/^\s*/ /; + if ($type eq 'message_id' || $type eq 'in_reply_to') + { + s/^\s*(<.*>)\s*/$1/; + } $values{$type} .= $_; } } @@ -421,8 +440,10 @@ sub update_table goto restart; # Some mails may have duplicated messages } - $q = "INSERT INTO $opt_table ("; + $q = "INSERT INTO my_mail ("; $q.= "mail_id,"; + $q.= "message_id,"; + $q.= "in_reply_to,"; $q.= "date,"; $q.= "time_zone,"; $q.= "mail_from,"; @@ -435,6 +456,12 @@ sub update_table $q.= "hash"; $q.= ") VALUES ("; $q.= "NULL,"; + $q.= (defined($values->{'message_id'}) ? + $dbh->quote($values->{'message_id'}) : "NULL"); + $q.= ","; + $q.= (defined($values->{'in_reply_to'}) ? + $dbh->quote($values->{'in_reply_to'}) : "NULL"); + $q.= ","; $q.= "'" . $values->{'date'} . "',"; $q.= (defined($values->{'time_zone'}) ? $dbh->quote($values->{'time_zone'}) : "NULL"); @@ -575,7 +602,6 @@ Options: --port=# TCP/IP port to be used with connection. --socket=... MySQL UNIX socket to be used with connection. --db=... Database to be used. ---table=... Table name for mails. --user=... Username for connecting. --password=... Password for the user. --stdin Read mails from stdin. diff --git a/tests/pmail.pl b/tests/pmail.pl index c7f8d4ee368..02d5d60ac0f 100755 --- a/tests/pmail.pl +++ b/tests/pmail.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # # Prints mails to standard output # @@ -9,21 +9,25 @@ use DBI; use Getopt::Long; -$VER="1.5"; +$VER="2.0"; @fldnms= ("mail_from","mail_to","cc","date","time_zone","file","sbj","txt"); -$fields=8; -@mail= (@from,@to,@cc,@date,@time_zone,@file,@sbj,@txt); +my $fields= 0; +my $base_q= ""; +my $mail_count= 0; $opt_user= $opt_password= ""; $opt_socket= "/tmp/mysql.sock"; $opt_port= 3306; $opt_db="mail"; -$opt_table="mails"; +$opt_table="my_mail"; $opt_help=$opt_count=0; +$opt_thread= 0; +$opt_host= ""; +$opt_message_id= 0; GetOptions("help","count","port=i","db=s","table=s","host=s","password=s", - "user=s","socket=s") || usage(); + "user=s","socket=s", "thread","message_id") || usage(); if ($opt_host eq '') { @@ -39,81 +43,194 @@ if ($opt_help || !$ARGV[0]) #### Connect and parsing the query to MySQL #### -$dbh= DBI->connect("DBI:mysql:$opt_db:$opt_host:port=$opt_port:mysql_socket=$opt_mysql_socket", $opt_user,$opt_password, { PrintError => 0}) +$dbh= DBI->connect("DBI:mysql:$opt_db:$opt_host:port=$opt_port:mysql_socket=$opt_socket", $opt_user,$opt_password, { PrintError => 0}) || die $DBI::errstr; -if ($opt_count) +main(); + +#### +#### main +#### + +sub main { - count_mails(); + my ($row, $val, $q, $mail, $sth); + + if ($opt_count) + { + count_mails(); + } + + $base_q= "SELECT "; + foreach $val (@fldnms) + { + if (!$fields) + { + $base_q.= "$val"; + } + else + { + $base_q.= ",$val"; + } + $fields++; + } + $base_q.= ",message_id" if ($opt_thread || $opt_message_id); + $base_q.= " FROM $opt_table"; + $q= " WHERE $ARGV[0]"; + + $sth= $dbh->prepare($base_q . $q); + if (!$sth->execute) + { + print "$DBI::errstr\n"; + $sth->finish; + die; + } + for (; ($row= $sth->fetchrow_arrayref); $mail_count++) + { + for ($i= 0; $i < $fields; $i++) + { + if ($opt_message_id) + { + $mail[$fields][$mail_count]= $row->[$fields]; + $mail[$fields][$mail_count].= "\nNumber of Replies: " . get_nr_replies($row->[$fields]); + } + $mail[$i][$mail_count]= $row->[$i]; + } + if ($opt_thread) + { + get_mail_by_message_id($row->[$fields], $mail); + } + } + print_mails($mail); } -$fields=0; -$query = "select "; -foreach $val (@fldnms) +#### +#### Function, which fetches mail by searching in-reply-to with +#### a given message_id. Saves the value (mail) in mail variable. +#### Returns the message id of the mail found and searches again +#### and saves, until no more mails are found with that message_id. +#### + +sub get_mail_by_message_id { - if (!$fields) + my ($message_id, $mail)= @_; + my ($q, $query, $i, $row, $sth); + + $q= " WHERE in_reply_to = \"$message_id\""; + $query= $base_q . $q; + $sth= $dbh->prepare($query); + if (!$sth->execute) { - $query.= "$val"; + print "QUERY: $query\n$DBI::errstr\n"; + $sth->finish; + die; + } + while (($row= $sth->fetchrow_arrayref)) + { + $mail_count++; + for ($i= 0; $i < $fields; $i++) + { + if ($opt_message_id) + { + $mail[$fields][$mail_count]= $row->[$fields]; + $mail[$fields][$mail_count].= "\nNumber of Replies: " . get_nr_replies($row->[$fields]); + } + $mail[$i][$mail_count]= $row->[$i]; + } + $new_message_id= $row->[$fields]; + if (defined($new_message_id) && length($new_message_id)) + { + get_mail_by_message_id($new_message_id, $mail); + } + } + return; +} + +#### +#### Get number of replies for a given message_id +#### + +sub get_nr_replies +{ + my ($message_id)= @_; + my ($sth, $sth2, $q, $row, $row2, $nr_replies); + + $nr_replies= 0; + $q= "SELECT COUNT(*) FROM my_mail WHERE in_reply_to=\"$message_id\""; + $sth= $dbh->prepare($q); + if (!$sth->execute) + { + print "QUERY: $q\n$DBI::errstr\n"; + $sth->finish; + die; + } + while (($row= $sth->fetchrow_arrayref)) + { + if (($nr_replies= $row->[0])) + { + $q= "SELECT message_id FROM my_mail WHERE in_reply_to=\"$message_id\""; + $sth2= $dbh->prepare($q); + if (!$sth2->execute) + { + print "QUERY: $q\n$DBI::errstr\n"; + $sth->finish; + die; + } + while (($row2= $sth2->fetchrow_arrayref)) + { + # There may be several replies to the same mail. Also the + # replies to the 'parent' mail may contain several replies + # and so on. Thus we need to calculate it recursively. + $nr_replies+= get_nr_replies($row2->[0]); + } + } + return $nr_replies; + } +} + +#### +#### Print mails +#### + +sub print_mails +{ + my ($mail)= @_; + my ($i); + + for ($i=0; $mail[0][$i]; $i++) + { + print "#" x 33; + print " " . ($i+1) . ". Mail "; + print "#" x 33; + print "\n"; + if ($opt_message_id) + { + print "Msg ID: $mail[$fields][$i]\n"; + } + print "From: $mail[0][$i]\n"; + print "To: $mail[1][$i]\n"; + print "Cc:" . (defined($mail[2][$i]) ? $mail[2][$i] : "") . "\n"; + print "Date: $mail[3][$i]\n"; + print "Timezone: $mail[4][$i]\n"; + print "File: $mail[5][$i]\n"; + print "Subject: $mail[6][$i]\n"; + print "Message:\n$mail[7][$i]\n"; + } + print "#" x 20; + print " Summary: "; + if ($i == 1) + { + print "$i Mail "; + print "matches the query "; } else { - $query.= ",$val"; + print "$i Mails "; + print "match the query "; } - $fields++; -} -$query.= " from $opt_table where $ARGV[0] order by date desc"; - -#### -#### Send query and save result -#### - -$sth= $dbh->prepare($query); -if (!$sth->execute) -{ - print "$DBI::errstr\n"; - $sth->finish; - die; -} -for ($i=0; ($row= $sth->fetchrow_arrayref); $i++) -{ - for ($j=0; $j < $fields; $j++) - { - $mail[$j][$i]= $row->[$j]; - } -} - -#### -#### Print to stderr -#### - -for ($i=0; $mail[0][$i]; $i++) -{ - print "#" x 33; - print " " . ($i+1) . ". Mail "; - print "#" x 33; - print "\nFrom: $mail[0][$i]\n"; - print "To: $mail[1][$i]\n"; - print "Cc: $mail[2][$i]\n"; - print "Date: $mail[3][$i]\n"; - print "Timezone: $mail[4][$i]\n"; - print "File: $mail[5][$i]\n"; - print "Subject: $mail[6][$i]\n"; - print "Message:\n$mail[7][$i]\n"; -} -print "#" x 20; -print " Summary: "; -if ($i == 1) -{ - print "$i Mail "; - print "matches the query "; -} -else -{ - print "$i Mails "; - print "match the query "; -} -print "#" x 20; -print "\n"; + print "#" x 20; + print "\n"; +} #### #### Count mails that matches the query, but don't show them @@ -121,6 +238,8 @@ print "\n"; sub count_mails { + my ($sth); + $sth= $dbh->prepare("select count(*) from $opt_table where $ARGV[0]"); if (!$sth->execute) { @@ -154,15 +273,21 @@ sub usage Usage: pmail [options] "SQL where clause" Options: - --help show this help - --count Shows how many mails matches the query, but not the mails. - --db= database to use (Default: $opt_db) - --table= table to use (Default: $opt_table) - --host= Hostname which to connect (Default: $opt_host) - --socket= Unix socket to be used for connection (Default: $opt_socket) - --password= Password to use for mysql - --user= User to be used for mysql connection, if not current user - --port= mysql port to be used (Default: $opt_port) + --help show this help + --count Shows how many mails matches the query, but not the mails. + --db= database to use (Default: $opt_db) + --host= Hostname which to connect (Default: $opt_host) + --socket= Unix socket to be used for connection (Default: $opt_socket) + --password= Password to use for mysql + --user= User to be used for mysql connection, if not current user + --port= mysql port to be used (Default: $opt_port) + --thread Will search for possible replies to emails found by the search + criteria. Replies, if found, will be displayed right after the + original mail. + --message_id Display message_id on top of each mail. Useful when searching + email threads with --thread. On the second line is the number + of replies to the same thread, starting counting from that + mail (excluding possible parent mails). "SQL where clause" is the end of the select clause, where the condition is expressed. The result will be the mail(s) that matches the condition and @@ -176,18 +301,20 @@ sub usage - Subject - Message text The field names that can be used in the where clause are: - Field Type - - mail_from varchar(120) - - date datetime - - sbj varchar(200) - - txt mediumtext - - cc text - - mail_to text - - time_zone varchar(6) - - reply varchar(120) - - file varchar(32) - - hash int(11) - An example of the pmail: + Field Type + - message_id varchar(255) # Use with --thread and --message_id + - in_reply_to varchar(255) # Internally used by --thread + - mail_from varchar(120) + - date datetime + - sbj varchar(200) + - txt mediumtext + - cc text + - mail_to text + - time_zone varchar(6) + - reply varchar(120) + - file varchar(32) + - hash int(11) + An example of pmail: pmail "txt like '%libmysql.dll%' and sbj like '%delphi%'" NOTE: the txt field is NOT case sensitive! EOF From dbae73bfa8000ee83e8dfece70e21ded4c505807 Mon Sep 17 00:00:00 2001 From: "pekka@mysql.com" <> Date: Sun, 10 Apr 2005 07:55:30 +0200 Subject: [PATCH 81/83] ndb - testOIBasic.cpp: 4.1->5.0 fix --- ndb/test/ndbapi/testOIBasic.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp index 96926a421fb..9df983ebe99 100644 --- a/ndb/test/ndbapi/testOIBasic.cpp +++ b/ndb/test/ndbapi/testOIBasic.cpp @@ -482,16 +482,17 @@ Chs::Chs(CHARSET_INFO* cs) : for (unsigned j = 0; j < size; j++) { bytes[j] = urandom(256); } + int not_used; // check wellformed const char* sbytes = (const char*)bytes; - if ((*cs->cset->well_formed_len)(cs, sbytes, sbytes + size, 1) != size) { + if ((*cs->cset->well_formed_len)(cs, sbytes, sbytes + size, 1, ¬_used) != size) { miss1++; continue; } // check no proper prefix wellformed ok = true; for (unsigned j = 1; j < size; j++) { - if ((*cs->cset->well_formed_len)(cs, sbytes, sbytes + j, 1) == j) { + if ((*cs->cset->well_formed_len)(cs, sbytes, sbytes + j, 1, ¬_used) == j) { ok = false; break; } @@ -676,7 +677,8 @@ Col::wellformed(const void* addr) const CHARSET_INFO* cs = m_chs->m_cs; const char* src = (const char*)addr; unsigned len = m_bytelength; - assert((*cs->cset->well_formed_len)(cs, src, src + len, 0xffff) == len); + int not_used; + assert((*cs->cset->well_formed_len)(cs, src, src + len, 0xffff, ¬_used) == len); } break; case Col::Varchar: @@ -685,8 +687,9 @@ Col::wellformed(const void* addr) const const unsigned char* src = (const unsigned char*)addr; const char* ssrc = (const char*)src; unsigned len = src[0]; + int not_used; assert(len <= m_bytelength); - assert((*cs->cset->well_formed_len)(cs, ssrc + 1, ssrc + 1 + len, 0xffff) == len); + assert((*cs->cset->well_formed_len)(cs, ssrc + 1, ssrc + 1 + len, 0xffff, ¬_used) == len); } break; case Col::Longvarchar: @@ -695,8 +698,9 @@ Col::wellformed(const void* addr) const const unsigned char* src = (const unsigned char*)addr; const char* ssrc = (const char*)src; unsigned len = src[0] + (src[1] << 8); + int not_used; assert(len <= m_bytelength); - assert((*cs->cset->well_formed_len)(cs, ssrc + 2, ssrc + 2 + len, 0xffff) == len); + assert((*cs->cset->well_formed_len)(cs, ssrc + 2, ssrc + 2 + len, 0xffff, ¬_used) == len); } break; default: From fc0e6aa274c876fac17705d37b6d802f0e7d02e0 Mon Sep 17 00:00:00 2001 From: "joerg@mysql.com" <> Date: Mon, 11 Apr 2005 11:24:30 +0200 Subject: [PATCH 82/83] Manual transfer of the change in "configure.in" (4.1) to "config/ac-macros/character_sets.m4". --- config/ac-macros/character_sets.m4 | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/config/ac-macros/character_sets.m4 b/config/ac-macros/character_sets.m4 index 6efd31fdb05..3ecc4bb5a03 100644 --- a/config/ac-macros/character_sets.m4 +++ b/config/ac-macros/character_sets.m4 @@ -359,16 +359,23 @@ case $default_charset in ;; utf8) default_charset_default_collation="utf8_general_ci" - define(UTFC1, utf8_general_ci utf8_bin) - define(UTFC2, utf8_czech_ci utf8_danish_ci) - define(UTFC3, utf8_estonian_ci utf8_icelandic_ci) - define(UTFC4, utf8_latvian_ci utf8_lithuanian_ci) - define(UTFC5, utf8_persian_ci utf8_polish_ci utf8_romanian_ci) - define(UTFC6, utf8_slovak_ci utf8_slovenian_ci) - define(UTFC7, utf8_spanish2_ci utf8_spanish_ci) - define(UTFC8, utf8_swedish_ci utf8_turkish_ci) - define(UTFC9, utf8_unicode_ci) - UTFC="UTFC1 UTFC2 UTFC3 UTFC4 UTFC5 UTFC6 UTFC7 UTFC8 UTFC9" + if test "$default_collation" = "utf8_general_cs"; then + # For those who explicitly desire "utf8_general_cs", support it, + # and then also set the CPP switch enabling that code. + UTFC="utf8_general_cs" + AC_DEFINE([HAVE_UTF8_GENERAL_CS], [1], [certain Japanese customer]) + else + define(UTFC1, utf8_general_ci utf8_bin) + define(UTFC2, utf8_czech_ci utf8_danish_ci) + define(UTFC3, utf8_estonian_ci utf8_icelandic_ci) + define(UTFC4, utf8_latvian_ci utf8_lithuanian_ci) + define(UTFC5, utf8_persian_ci utf8_polish_ci utf8_romanian_ci) + define(UTFC6, utf8_slovak_ci utf8_slovenian_ci) + define(UTFC7, utf8_spanish2_ci utf8_spanish_ci) + define(UTFC8, utf8_swedish_ci utf8_turkish_ci) + define(UTFC9, utf8_unicode_ci) + UTFC="UTFC1 UTFC2 UTFC3 UTFC4 UTFC5 UTFC6 UTFC7 UTFC8 UTFC9" + fi default_charset_collations="$UTFC" ;; *) From fd5b9f7ed7ef9b852752cc40f0b09a4883e787c4 Mon Sep 17 00:00:00 2001 From: "pekka@mysql.com" <> Date: Mon, 11 Apr 2005 12:43:58 +0200 Subject: [PATCH 83/83] ndb - csc#4847 - manual merge 4.1->5.0 --- ndb/include/ndbapi/NdbScanOperation.hpp | 2 +- ndb/src/ndbapi/NdbScanOperation.cpp | 28 ++++++++++++++++++------- ndb/src/ndbapi/NdbTransaction.cpp | 6 +++--- ndb/src/ndbapi/Ndblist.cpp | 11 ++++++++++ sql/ha_ndbcluster.cc | 4 ++-- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index 5da717148b5..1c9649195d2 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -115,7 +115,7 @@ public: /** * Close scan */ - void close(bool forceSend = false); + void close(bool forceSend = false, bool releaseOp = false); /** * Update current tuple diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 9cd78ec721b..5980f2588bc 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -633,8 +633,14 @@ NdbScanOperation::doSend(int ProcessorId) return 0; } -void NdbScanOperation::close(bool forceSend) +void NdbScanOperation::close(bool forceSend, bool releaseOp) { + DBUG_ENTER("NdbScanOperation::close"); + DBUG_PRINT("enter", ("this=%x tcon=%x con=%x force=%d release=%d", + (UintPtr)this, + (UintPtr)m_transConnection, (UintPtr)theNdbCon, + forceSend, releaseOp)); + if(m_transConnection){ if(DEBUG_NEXT_RESULT) ndbout_c("close() theError.code = %d " @@ -650,13 +656,21 @@ void NdbScanOperation::close(bool forceSend) Guard guard(tp->theMutexPtr); close_impl(tp, forceSend); - } while(0); - - theNdbCon->theScanningOp = 0; - theNdb->closeTransaction(theNdbCon); - - theNdbCon = 0; + } + + NdbConnection* tCon = theNdbCon; + NdbConnection* tTransCon = m_transConnection; + theNdbCon = NULL; m_transConnection = NULL; + + if (releaseOp && tTransCon) { + NdbIndexScanOperation* tOp = (NdbIndexScanOperation*)this; + tTransCon->releaseExecutedScanOperation(tOp); + } + + tCon->theScanningOp = 0; + theNdb->closeTransaction(tCon); + DBUG_VOID_RETURN; } void diff --git a/ndb/src/ndbapi/NdbTransaction.cpp b/ndb/src/ndbapi/NdbTransaction.cpp index c2ded3560fc..e32a7ddf70a 100644 --- a/ndb/src/ndbapi/NdbTransaction.cpp +++ b/ndb/src/ndbapi/NdbTransaction.cpp @@ -954,9 +954,9 @@ void releaseExecutedScanOperation(); Remark: Release scan op when hupp'ed trans closed (save memory) ******************************************************************************/ void -NdbConnection::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp) +NdbTransaction::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp) { - DBUG_ENTER("NdbConnection::releaseExecutedScanOperation"); + DBUG_ENTER("NdbTransaction::releaseExecutedScanOperation"); DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp)) // here is one reason to make op lists doubly linked @@ -977,7 +977,7 @@ NdbConnection::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp) } } DBUG_VOID_RETURN; -}//NdbConnection::releaseExecutedScanOperation() +}//NdbTransaction::releaseExecutedScanOperation() /***************************************************************************** NdbOperation* getNdbOperation(const char* aTableName); diff --git a/ndb/src/ndbapi/Ndblist.cpp b/ndb/src/ndbapi/Ndblist.cpp index df90f3378ab..6dfd76c160b 100644 --- a/ndb/src/ndbapi/Ndblist.cpp +++ b/ndb/src/ndbapi/Ndblist.cpp @@ -550,10 +550,21 @@ Remark: Add a NdbScanOperation object into the signal idlelist. void Ndb::releaseScanOperation(NdbIndexScanOperation* aScanOperation) { + DBUG_ENTER("Ndb::releaseScanOperation"); + DBUG_PRINT("enter", ("op=%x", (UintPtr)aScanOperation)); +#ifdef ndb_release_check_dup + { NdbIndexScanOperation* tOp = theScanOpIdleList; + while (tOp != NULL) { + assert(tOp != aScanOperation); + tOp = (NdbIndexScanOperation*)tOp->theNext; + } + } +#endif aScanOperation->next(theScanOpIdleList); aScanOperation->theNdbCon = NULL; aScanOperation->theMagicNumber = 0xFE11D2; theScanOpIdleList = aScanOperation; + DBUG_VOID_RETURN; } /*************************************************************************** diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 44fadd3e6cf..70e6e1d98f8 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2685,7 +2685,7 @@ int ha_ndbcluster::close_scan() m_ops_pending= 0; } - cursor->close(m_force_send); + cursor->close(m_force_send, true); m_active_cursor= m_multi_cursor= NULL; DBUG_RETURN(0); } @@ -5694,7 +5694,7 @@ ha_ndbcluster::read_multi_range_next(KEY_MULTI_RANGE ** multi_range_found_p) close_scan: if (res == 1) { - m_multi_cursor->close(); + m_multi_cursor->close(false, true); m_active_cursor= m_multi_cursor= 0; DBUG_MULTI_RANGE(8); continue;