diff options
45 files changed, 657 insertions, 79 deletions
diff --git a/client/mysqltest.c b/client/mysqltest.c index 2d9ee74891c..7eb80e4594f 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -496,6 +496,10 @@ void handle_error(struct st_command*, void handle_no_error(struct st_command*); #ifdef EMBEDDED_LIBRARY + +/* attributes of the query thread */ +pthread_attr_t cn_thd_attrib; + /* send_one_query executes query in separate thread what is necessary in embedded library to run 'send' in proper way. @@ -534,7 +538,7 @@ static int do_send_query(struct st_connection *cn, const char *q, int q_len, cn->cur_query= q; cn->cur_query_len= q_len; cn->query_done= 0; - if (pthread_create(&tid, NULL, send_one_query, (void*)cn)) + if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn)) die("Cannot start new thread for query"); return 0; @@ -6170,6 +6174,12 @@ int main(int argc, char **argv) next_con= connections + 1; cur_con= connections; +#ifdef EMBEDDED_LIBRARY + /* set appropriate stack for the 'query' threads */ + (void) pthread_attr_init(&cn_thd_attrib); + pthread_attr_setstacksize(&cn_thd_attrib, DEFAULT_THREAD_STACK); +#endif /*EMBEDDED_LIBRARY*/ + /* Init file stack */ memset(file_stack, 0, sizeof(file_stack)); file_stack_end= diff --git a/mysql-test/r/error_simulation.result b/mysql-test/r/error_simulation.result new file mode 100644 index 00000000000..805e8fabbd8 --- /dev/null +++ b/mysql-test/r/error_simulation.result @@ -0,0 +1,19 @@ +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE t1 ( +a varchar(32) character set utf8 collate utf8_bin NOT NULL, +b varchar(32) character set utf8 collate utf8_bin NOT NULL ) +ENGINE=MyISAM DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES +('AAAAAAAAAA','AAAAAAAAAA'), ('AAAAAAAAAB','AAAAAAAAAB '), +('AAAAAAAAAB','AAAAAAAAAB'), ('AAAAAAAAAC','AAAAAAAAAC'), +('AAAAAAAAAD','AAAAAAAAAD'), ('AAAAAAAAAE','AAAAAAAAAE'), +('AAAAAAAAAF','AAAAAAAAAF'), ('AAAAAAAAAG','AAAAAAAAAG'), +('AAAAAAAAAH','AAAAAAAAAH'), ('AAAAAAAAAI','AAAAAAAAAI'), +('AAAAAAAAAJ','AAAAAAAAAJ'), ('AAAAAAAAAK','AAAAAAAAAK'); +set tmp_table_size=1024; +SELECT MAX(a) FROM t1 GROUP BY a,b; +ERROR 23000: Can't write; duplicate key in table '' +set tmp_table_size=default; +DROP TABLE t1; diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 73e5b054f80..d1f292cda0c 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -864,4 +864,25 @@ SELECT Overlaps(@horiz1, @point2) FROM DUAL; Overlaps(@horiz1, @point2) 0 DROP TABLE t1; +create table t1(f1 geometry, f2 point, f3 linestring); +select f1 from t1 union select f1 from t1; +f1 +insert into t1 (f2,f3) values (GeomFromText('POINT(1 1)'), +GeomFromText('LINESTRING(0 0,1 1,2 2)')); +select AsText(f2),AsText(f3) from t1; +AsText(f2) AsText(f3) +POINT(1 1) LINESTRING(0 0,1 1,2 2) +select AsText(a) from (select f2 as a from t1 union select f3 from t1) t; +AsText(a) +POINT(1 1) +LINESTRING(0 0,1 1,2 2) +create table t2 as select f2 as a from t1 union select f3 from t1; +desc t2; +Field Type Null Key Default Extra +a point YES NULL +select AsText(a) from t2; +AsText(a) +POINT(1 1) +LINESTRING(0 0,1 1,2 2) +drop table t1, t2; End of 5.0 tests diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 93098e68070..6de9a83aeed 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -403,4 +403,22 @@ use test; drop database mysqltest_1; drop database mysqltest_2; drop user mysqltest_u1@localhost; +grant all on `mysqltest\_%`.* to mysqltest_1@localhost with grant option; +grant usage on *.* to mysqltest_2@localhost; +create database mysqltest_1; +use mysqltest_1; +create table t1 (f1 int); +grant create on `mysqltest\_1`.* to mysqltest_2@localhost; +grant select on mysqltest_1.t1 to mysqltest_2@localhost; +create database mysqltest_3; +ERROR 42000: Access denied for user 'mysqltest_2'@'localhost' to database 'mysqltest_3' +use mysqltest_1; +create table t2(f1 int); +select * from t1; +f1 +drop database mysqltest_1; +revoke all privileges, grant option from mysqltest_1@localhost; +revoke all privileges, grant option from mysqltest_2@localhost; +drop user mysqltest_1@localhost; +drop user mysqltest_2@localhost; End of 5.0 tests diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index db703df1f52..4947fd7aecc 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1315,3 +1315,14 @@ TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1 TRIGGERS information_schema.TRIGGERS 1 USER_PRIVILEGES information_schema.USER_PRIVILEGES 1 VIEWS information_schema.VIEWS 1 +create table t1(f1 int); +create view v1 as select f1+1 as a from t1; +create table t2 (f1 int, f2 int); +create view v2 as select f1+1 as a, f2 as b from t2; +select table_name, is_updatable from information_schema.views; +table_name is_updatable +v1 NO +v2 YES +delete from v1; +drop view v1,v2; +drop table t1,t2; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 34eb831e7db..bb252b20a48 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -625,4 +625,40 @@ t1 CREATE TABLE `t1` ( `a` int(11) default NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='123' drop table t1; +CREATE TABLE t1 (a CHAR(2), KEY (a)) ENGINE = InnoDB DEFAULT CHARSET=UTF8; +INSERT INTO t1 VALUES ('uk'),('bg'); +SELECT * FROM t1 WHERE a = 'uk'; +a +uk +DELETE FROM t1 WHERE a = 'uk'; +SELECT * FROM t1 WHERE a = 'uk'; +a +UPDATE t1 SET a = 'us' WHERE a = 'uk'; +SELECT * FROM t1 WHERE a = 'uk'; +a +CREATE TABLE t2 (a CHAR(2), KEY (a)) ENGINE = InnoDB; +INSERT INTO t2 VALUES ('uk'),('bg'); +SELECT * FROM t2 WHERE a = 'uk'; +a +uk +DELETE FROM t2 WHERE a = 'uk'; +SELECT * FROM t2 WHERE a = 'uk'; +a +INSERT INTO t2 VALUES ('uk'); +UPDATE t2 SET a = 'us' WHERE a = 'uk'; +SELECT * FROM t2 WHERE a = 'uk'; +a +CREATE TABLE t3 (a CHAR(2), KEY (a)) ENGINE = MyISAM; +INSERT INTO t3 VALUES ('uk'),('bg'); +SELECT * FROM t3 WHERE a = 'uk'; +a +uk +DELETE FROM t3 WHERE a = 'uk'; +SELECT * FROM t3 WHERE a = 'uk'; +a +INSERT INTO t3 VALUES ('uk'); +UPDATE t3 SET a = 'us' WHERE a = 'uk'; +SELECT * FROM t3 WHERE a = 'uk'; +a +DROP TABLE t1,t2,t3; End of 5.0 tests diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result index b3bca7517f3..20cde86101e 100644 --- a/mysql-test/r/insert_update.result +++ b/mysql-test/r/insert_update.result @@ -393,3 +393,17 @@ id c1 cnt 1 0 3 2 2 1 DROP TABLE t1; +create table t1(f1 int primary key, +f2 timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP); +insert into t1(f1) values(1); +select @stamp1:=f2 from t1; +@stamp1:=f2 +# +insert into t1(f1) values(1) on duplicate key update f1=1; +select @stamp2:=f2 from t1; +@stamp2:=f2 +# +select if( @stamp1 = @stamp2, "correct", "wrong"); +if( @stamp1 = @stamp2, "correct", "wrong") +correct +drop table t1; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index ba487cb859d..efd6a5ab572 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -2853,7 +2853,6 @@ a 3 4 DROP TABLE t1,t2,t3; -purge master logs before (select adddate(current_timestamp(), interval -4 day)); CREATE TABLE t1 (f1 INT); CREATE TABLE t2 (f2 INT); INSERT INTO t1 VALUES (1); @@ -4081,4 +4080,30 @@ id select_type table type possible_keys key key_len ref rows Extra Warnings: Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res` DROP TABLE t1; +CREATE TABLE t1 ( +a varchar(255) default NULL, +b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, +INDEX idx(a,b) +); +CREATE TABLE t2 ( +a varchar(255) default NULL +); +INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24'); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26'); +INSERT INTO `t2` VALUES ('abcdefghijk'); +INSERT INTO `t2` VALUES ('asdf'); +SET session sort_buffer_size=8192; +SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2; +d1 +1 +1 +DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/r/subselect_notembedded.result b/mysql-test/r/subselect_notembedded.result index dd4b0701c32..44ae055425e 100644 --- a/mysql-test/r/subselect_notembedded.result +++ b/mysql-test/r/subselect_notembedded.result @@ -1 +1,3 @@ purge master logs before (select adddate(current_timestamp(), interval -4 day)); +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 'select adddate(current_timestamp(), interval -4 day))' at line 1 +purge master logs before adddate(current_timestamp(), interval -4 day); diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index fd9b15ab8ed..5405a632aa4 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -1454,19 +1454,22 @@ CREATE TABLE t2 (id INTEGER); INSERT INTO t2 VALUES (1),(2); CREATE TRIGGER t1_test AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (new.id); -SELECT GET_LOCK('B26162',20); -GET_LOCK('B26162',20) +SELECT GET_LOCK('B26162',120); +GET_LOCK('B26162',120) 1 -SELECT 'rl_acquirer', GET_LOCK('B26162',5), id FROM t2 WHERE id = 1; +SELECT 'rl_acquirer', GET_LOCK('B26162',120), id FROM t2 WHERE id = 1; SET SESSION LOW_PRIORITY_UPDATES=1; SET GLOBAL LOW_PRIORITY_UPDATES=1; INSERT INTO t1 VALUES (5); SELECT 'rl_contender', id FROM t2 WHERE id > 1; SELECT RELEASE_LOCK('B26162'); RELEASE_LOCK('B26162') -0 -rl_acquirer GET_LOCK('B26162',5) id -rl_acquirer 0 1 +1 +rl_acquirer GET_LOCK('B26162',120) id +rl_acquirer 1 1 +SELECT RELEASE_LOCK('B26162'); +RELEASE_LOCK('B26162') +1 rl_contender id rl_contender 2 DROP TRIGGER t1_test; diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index ba02f19712a..9e47b5da2b6 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -411,3 +411,19 @@ if(@bug28261 = f1, '', @bug28261:= f1) 2001-01-01 2002-02-02 drop table t1; +create table t1(f1 datetime); +insert into t1 values('2001-01-01'),('2002-02-02'); +select * from t1 where f1 between 20020101 and 20070101000000; +f1 +2002-02-02 00:00:00 +select * from t1 where f1 between 2002010 and 20070101000000; +f1 +2001-01-01 00:00:00 +2002-02-02 00:00:00 +Warnings: +Warning 1292 Incorrect datetime value: '2002010' for column 'f1' at row 1 +select * from t1 where f1 between 20020101 and 2007010100000; +f1 +Warnings: +Warning 1292 Incorrect datetime value: '2007010100000' for column 'f1' at row 1 +drop table t1; diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index c9c42d18d68..3cf24529421 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -790,3 +790,12 @@ Warning 1292 Truncated incorrect datetime value: '0000-00-00' Warning 1292 Truncated incorrect datetime value: '0000-00-00' Warning 1292 Truncated incorrect datetime value: '0000-00-00' drop table t1; +CREATE TABLE t1 ( +qty decimal(16,6) default NULL, +dps tinyint(3) unsigned default NULL +); +INSERT INTO t1 VALUES (1.1325,3); +SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1; +ROUND(qty,3) dps ROUND(qty,dps) +1.133 3 1.133 +DROP TABLE t1; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 43e147724c8..3757c5fd451 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -23,6 +23,9 @@ c 5 6 11 +select is_updatable from information_schema.views where table_name='v1'; +is_updatable +NO create temporary table t1 (a int, b int); select * from t1; a b @@ -322,6 +325,12 @@ create table t1 (a int, b int, primary key(a)); insert into t1 values (10,2), (20,3), (30,4), (40,5), (50,10); create view v1 (a,c) as select a, b+1 from t1; create algorithm=temptable view v2 (a,c) as select a, b+1 from t1; +select is_updatable from information_schema.views where table_name='v2'; +is_updatable +NO +select is_updatable from information_schema.views where table_name='v1'; +is_updatable +YES update v1 set c=a+c; ERROR HY000: Column 'c' is not updatable update v2 set a=a+c; @@ -604,6 +613,10 @@ insert into t1 values(5,'Hello, world of views'); create view v1 as select * from t1; create view v2 as select * from v1; update v2 set col2='Hello, view world'; +select is_updatable from information_schema.views; +is_updatable +YES +YES select * from t1; col1 col2 5 Hello, view world diff --git a/mysql-test/t/error_simulation-master.opt b/mysql-test/t/error_simulation-master.opt new file mode 100644 index 00000000000..edb77cfa85e --- /dev/null +++ b/mysql-test/t/error_simulation-master.opt @@ -0,0 +1 @@ +--loose-debug=d,raise_error diff --git a/mysql-test/t/error_simulation.test b/mysql-test/t/error_simulation.test new file mode 100644 index 00000000000..8c044224b8a --- /dev/null +++ b/mysql-test/t/error_simulation.test @@ -0,0 +1,29 @@ +-- source include/have_debug.inc + +# +# Bug #28499: crash for grouping query when tmp_table_size is too small +# + +DROP TABLE IF EXISTS t1; + +CREATE TABLE t1 ( + a varchar(32) character set utf8 collate utf8_bin NOT NULL, + b varchar(32) character set utf8 collate utf8_bin NOT NULL ) +ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO t1 VALUES + ('AAAAAAAAAA','AAAAAAAAAA'), ('AAAAAAAAAB','AAAAAAAAAB '), + ('AAAAAAAAAB','AAAAAAAAAB'), ('AAAAAAAAAC','AAAAAAAAAC'), + ('AAAAAAAAAD','AAAAAAAAAD'), ('AAAAAAAAAE','AAAAAAAAAE'), + ('AAAAAAAAAF','AAAAAAAAAF'), ('AAAAAAAAAG','AAAAAAAAAG'), + ('AAAAAAAAAH','AAAAAAAAAH'), ('AAAAAAAAAI','AAAAAAAAAI'), + ('AAAAAAAAAJ','AAAAAAAAAJ'), ('AAAAAAAAAK','AAAAAAAAAK'); + +set tmp_table_size=1024; + +--error ER_DUP_KEY +SELECT MAX(a) FROM t1 GROUP BY a,b; + +set tmp_table_size=default; + +DROP TABLE t1; diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index ccc38db8dea..95ccc6272e2 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -557,4 +557,17 @@ SELECT Overlaps(@horiz1, @point2) FROM DUAL; DROP TABLE t1; +# +# Bug#28763: Selecting geometry fields in UNION caused server crash. +# +create table t1(f1 geometry, f2 point, f3 linestring); +select f1 from t1 union select f1 from t1; +insert into t1 (f2,f3) values (GeomFromText('POINT(1 1)'), + GeomFromText('LINESTRING(0 0,1 1,2 2)')); +select AsText(f2),AsText(f3) from t1; +select AsText(a) from (select f2 as a from t1 union select f3 from t1) t; +create table t2 as select f2 as a from t1 union select f3 from t1; +desc t2; +select AsText(a) from t2; +drop table t1, t2; --echo End of 5.0 tests diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 4a3324b1833..a3a8e2d5d53 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -555,5 +555,35 @@ drop database mysqltest_1; drop database mysqltest_2; drop user mysqltest_u1@localhost; +# +# Bug#18660 Can't grant any privileges on single table in database +# with underscore char +# +grant all on `mysqltest\_%`.* to mysqltest_1@localhost with grant option; +grant usage on *.* to mysqltest_2@localhost; +connect (con18600_1,localhost,mysqltest_1,,); + +create database mysqltest_1; +use mysqltest_1; +create table t1 (f1 int); + +grant create on `mysqltest\_1`.* to mysqltest_2@localhost; +grant select on mysqltest_1.t1 to mysqltest_2@localhost; +connect (con3,localhost,mysqltest_2,,); +connection con3; +--error 1044 +create database mysqltest_3; +use mysqltest_1; +create table t2(f1 int); +select * from t1; +connection default; +drop database mysqltest_1; + +revoke all privileges, grant option from mysqltest_1@localhost; +revoke all privileges, grant option from mysqltest_2@localhost; +drop user mysqltest_1@localhost; +drop user mysqltest_2@localhost; + + --echo End of 5.0 tests diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index f8922317eb3..1d368ac6075 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1023,4 +1023,19 @@ where t.table_schema = 'information_schema' and group by c2.column_type order by num limit 1) group by t.table_name order by num1, t.table_name; +# +# Bug#28266 IS_UPDATABLE field on VIEWS table in I_S database is wrong +# +create table t1(f1 int); +create view v1 as select f1+1 as a from t1; +create table t2 (f1 int, f2 int); +create view v2 as select f1+1 as a, f2 as b from t2; +select table_name, is_updatable from information_schema.views; +# +# Note: we can perform 'delete' for non updatable view. +# +delete from v1; +drop view v1,v2; +drop table t1,t2; + # End of 5.0 tests. diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index e6d94fe1627..0c53705cf71 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -605,4 +605,35 @@ alter table t1 comment '123'; show create table t1; drop table t1; +# +# Bug #25866: Getting "#HY000 Can't find record in..." on and INSERT +# +CREATE TABLE t1 (a CHAR(2), KEY (a)) ENGINE = InnoDB DEFAULT CHARSET=UTF8; +INSERT INTO t1 VALUES ('uk'),('bg'); +SELECT * FROM t1 WHERE a = 'uk'; +DELETE FROM t1 WHERE a = 'uk'; +SELECT * FROM t1 WHERE a = 'uk'; +UPDATE t1 SET a = 'us' WHERE a = 'uk'; +SELECT * FROM t1 WHERE a = 'uk'; + +CREATE TABLE t2 (a CHAR(2), KEY (a)) ENGINE = InnoDB; +INSERT INTO t2 VALUES ('uk'),('bg'); +SELECT * FROM t2 WHERE a = 'uk'; +DELETE FROM t2 WHERE a = 'uk'; +SELECT * FROM t2 WHERE a = 'uk'; +INSERT INTO t2 VALUES ('uk'); +UPDATE t2 SET a = 'us' WHERE a = 'uk'; +SELECT * FROM t2 WHERE a = 'uk'; + +CREATE TABLE t3 (a CHAR(2), KEY (a)) ENGINE = MyISAM; +INSERT INTO t3 VALUES ('uk'),('bg'); +SELECT * FROM t3 WHERE a = 'uk'; +DELETE FROM t3 WHERE a = 'uk'; +SELECT * FROM t3 WHERE a = 'uk'; +INSERT INTO t3 VALUES ('uk'); +UPDATE t3 SET a = 'us' WHERE a = 'uk'; +SELECT * FROM t3 WHERE a = 'uk'; + +DROP TABLE t1,t2,t3; + --echo End of 5.0 tests diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test index 725fbdb25d7..67108744ec6 100644 --- a/mysql-test/t/insert_update.test +++ b/mysql-test/t/insert_update.test @@ -290,3 +290,19 @@ INSERT IGNORE INTO t1 (id,c1) SELECT * FROM t2 SELECT * FROM t1; DROP TABLE t1; + +# +# Bug#28904: INSERT .. ON DUPLICATE was silently updating rows when it +# shouldn't. +# +create table t1(f1 int primary key, + f2 timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP); +insert into t1(f1) values(1); +--replace_column 1 # +select @stamp1:=f2 from t1; +--sleep 2 +insert into t1(f1) values(1) on duplicate key update f1=1; +--replace_column 1 # +select @stamp2:=f2 from t1; +select if( @stamp1 = @stamp2, "correct", "wrong"); +drop table t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index d565070835e..12688fa4cf4 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1822,13 +1822,6 @@ SELECT * FROM t1 DROP TABLE t1,t2,t3; # -# BUG #10308: purge log with subselect -# - -purge master logs before (select adddate(current_timestamp(), interval -4 day)); - - -# # Bug#18503: Queries with a quantified subquery returning empty set may # return a wrong result. # @@ -2920,4 +2913,36 @@ SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res; DROP TABLE t1; +# +# Bug #28811: crash for query containing subquery with ORDER BY and LIMIT 1 +# + +CREATE TABLE t1 ( + a varchar(255) default NULL, + b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, + INDEX idx(a,b) +); +CREATE TABLE t2 ( + a varchar(255) default NULL +); + +INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24'); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26'); +INSERT INTO `t2` VALUES ('abcdefghijk'); +INSERT INTO `t2` VALUES ('asdf'); + +SET session sort_buffer_size=8192; + +SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2; + +DROP TABLE t1,t2; + --echo End of 5.0 tests. diff --git a/mysql-test/t/subselect_notembedded.test b/mysql-test/t/subselect_notembedded.test index c5b23f6dac8..c112272e8ad 100644 --- a/mysql-test/t/subselect_notembedded.test +++ b/mysql-test/t/subselect_notembedded.test @@ -1,8 +1,9 @@ -- source include/not_embedded.inc # -# BUG #10308: purge log with subselect +# BUG#10308: purge log with subselect +# Bug#28553: mysqld crash in "purge master log before(select time from information_schema)" # - +--error 1064 purge master logs before (select adddate(current_timestamp(), interval -4 day)); - +purge master logs before adddate(current_timestamp(), interval -4 day); diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index 363df94eeb3..7158d02956e 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -1763,6 +1763,9 @@ select * from t1; select * from t3; drop table t1, t2, t3; +disconnect addconroot1; +disconnect addconroot2; +disconnect addconwithoutdb; # # Bug #26162: Trigger DML ignores low_priority_updates setting # @@ -1776,19 +1779,23 @@ INSERT INTO t2 VALUES (1),(2); CREATE TRIGGER t1_test AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (new.id); +CONNECT (rl_holder, localhost, root,,); CONNECT (rl_acquirer, localhost, root,,); CONNECT (wl_acquirer, localhost, root,,); CONNECT (rl_contender, localhost, root,,); -SELECT GET_LOCK('B26162',20); +CONNECTION rl_holder; +SELECT GET_LOCK('B26162',120); CONNECTION rl_acquirer; --send -SELECT 'rl_acquirer', GET_LOCK('B26162',5), id FROM t2 WHERE id = 1; +SELECT 'rl_acquirer', GET_LOCK('B26162',120), id FROM t2 WHERE id = 1; CONNECTION wl_acquirer; SET SESSION LOW_PRIORITY_UPDATES=1; SET GLOBAL LOW_PRIORITY_UPDATES=1; +#need to wait for rl_acquirer to lock on the B26162 lock +sleep 2; --send INSERT INTO t1 VALUES (5); @@ -1798,13 +1805,16 @@ CONNECTION rl_contender; --send SELECT 'rl_contender', id FROM t2 WHERE id > 1; -CONNECTION default; +CONNECTION rl_holder; +#need to wait for wl_acquirer and rl_contender to lock on t2 +sleep 2; SELECT RELEASE_LOCK('B26162'); -CONNECTION wl_acquirer; ---reap CONNECTION rl_acquirer; --reap +SELECT RELEASE_LOCK('B26162'); +CONNECTION wl_acquirer; +--reap CONNECTION rl_contender; --reap @@ -1812,6 +1822,7 @@ CONNECTION default; DISCONNECT rl_acquirer; DISCONNECT wl_acquirer; DISCONNECT rl_contender; +DISCONNECT rl_holder; DROP TRIGGER t1_test; DROP TABLE t1,t2; diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index d420afbde37..ffda593f320 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -271,3 +271,14 @@ select if(@bug28261 = f1, '', @bug28261:= f1) from t1; select if(@bug28261 = f1, '', @bug28261:= f1) from t1; select if(@bug28261 = f1, '', @bug28261:= f1) from t1; drop table t1; + +# +# Bug#28778: Wrong result of BETWEEN when comparing a DATETIME field with an +# integer constants. +# +create table t1(f1 datetime); +insert into t1 values('2001-01-01'),('2002-02-02'); +select * from t1 where f1 between 20020101 and 20070101000000; +select * from t1 where f1 between 2002010 and 20070101000000; +select * from t1 where f1 between 20020101 and 2007010100000; +drop table t1; diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 4fdb0c8458f..5538f19f5f9 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -394,3 +394,17 @@ create table t1 as from (select 1 as s,'t' as t union select null, null ) as sub1; select group_concat(t) from t1 group by week(date)/10; drop table t1; + +# +# Bug#28980: ROUND(<dec expr>, <int col>) returned double values +# + +CREATE TABLE t1 ( + qty decimal(16,6) default NULL, + dps tinyint(3) unsigned default NULL +); +INSERT INTO t1 VALUES (1.1325,3); + +SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1; + +DROP TABLE t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index f574451af08..3c370da4139 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -32,6 +32,7 @@ create view v1 (c,d) as select a,b from t1 # simple view create view v1 (c) as select b+1 from t1; select c from v1; +select is_updatable from information_schema.views where table_name='v1'; # temporary table should not hide table of view create temporary table t1 (a int, b int); @@ -228,6 +229,8 @@ create table t1 (a int, b int, primary key(a)); insert into t1 values (10,2), (20,3), (30,4), (40,5), (50,10); create view v1 (a,c) as select a, b+1 from t1; create algorithm=temptable view v2 (a,c) as select a, b+1 from t1; +select is_updatable from information_schema.views where table_name='v2'; +select is_updatable from information_schema.views where table_name='v1'; # try to update expression -- error 1348 update v1 set c=a+c; @@ -497,6 +500,7 @@ insert into t1 values(5,'Hello, world of views'); create view v1 as select * from t1; create view v2 as select * from v1; update v2 set col2='Hello, view world'; +select is_updatable from information_schema.views; select * from t1; drop view v2, v1; drop table t1; diff --git a/sql/field.cc b/sql/field.cc index 83c17c43ee4..c8c6014b92c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6218,7 +6218,8 @@ uint Field_string::get_key_image(char *buff, uint length, imagetype type_arg) length / field_charset->mbmaxlen); memcpy(buff, ptr, bytes); if (bytes < length) - bzero(buff + bytes, length - bytes); + field_charset->cset->fill(field_charset, buff + bytes, length - bytes, + field_charset->pad_char); return bytes; } diff --git a/sql/field.h b/sql/field.h index 46efb150205..fb6534b7b55 100644 --- a/sql/field.h +++ b/sql/field.h @@ -360,7 +360,12 @@ public: { return field_length / charset()->mbmaxlen; } - + virtual geometry_type get_geometry_type() + { + /* shouldn't get here. */ + DBUG_ASSERT(0); + return GEOM_GEOMETRY; + } friend bool reopen_table(THD *,struct st_table *,bool); friend int cre_myisam(my_string name, register TABLE *form, uint options, ulonglong auto_increment_value); @@ -1324,6 +1329,7 @@ public: uint get_key_image(char *buff,uint length,imagetype type); uint size_of() const { return sizeof(*this); } int reset(void) { return !maybe_null() || Field_blob::reset(); } + geometry_type get_geometry_type() { return geom_type; }; }; #endif /*HAVE_SPATIAL*/ diff --git a/sql/filesort.cc b/sql/filesort.cc index a4bf04a6786..d518ddbb117 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -35,7 +35,8 @@ if (my_b_write((file),(byte*) (from),param->ref_length)) \ /* functions defined in this file */ -static char **make_char_array(register uint fields, uint length, myf my_flag); +static char **make_char_array(char **old_pos, register uint fields, + uint length, myf my_flag); static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffer_file, uint count); static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select, uchar * *sort_keys, IO_CACHE *buffer_file, @@ -202,9 +203,9 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, ulong old_memavl; ulong keys= memavl/(param.rec_length+sizeof(char*)); param.keys=(uint) min(records+1, keys); - if (table_sort.sort_keys || - (table_sort.sort_keys= (uchar **) make_char_array(param.keys, param.rec_length, - MYF(0)))) + if ((table_sort.sort_keys= + (uchar **) make_char_array((char **) table_sort.sort_keys, + param.keys, param.rec_length, MYF(0)))) break; old_memavl=memavl; if ((memavl=memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory) @@ -346,14 +347,16 @@ void filesort_free_buffers(TABLE *table, bool full) /* Make a array of string pointers */ -static char **make_char_array(register uint fields, uint length, myf my_flag) +static char **make_char_array(char **old_pos, register uint fields, + uint length, myf my_flag) { register char **pos; - char **old_pos,*char_pos; + char *char_pos; DBUG_ENTER("make_char_array"); - if ((old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)), - my_flag))) + if (old_pos || + (old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)), + my_flag))) { pos=old_pos; char_pos=((char*) (pos+fields)) -length; while (fields--) *(pos++) = (char_pos+= length); diff --git a/sql/item.cc b/sql/item.cc index a5dfa0db6b6..32c43eaa865 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4318,7 +4318,9 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table) case MYSQL_TYPE_GEOMETRY: return new Field_geom(max_length, maybe_null, name, table, (Field::geometry_type) - ((Item_geometry_func *)this)->get_geometry_type()); + ((type() == Item::TYPE_HOLDER) ? + ((Item_type_holder *)this)->get_geometry_type() : + ((Item_geometry_func *)this)->get_geometry_type())); } } @@ -6423,6 +6425,10 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item) if (Field::result_merge_type(fld_type) == INT_RESULT) decimals= 0; prev_decimal_int_part= item->decimal_int_part(); + if (item->field_type() == MYSQL_TYPE_GEOMETRY) + geometry_type= (item->type() == Item::FIELD_ITEM) ? + ((Item_field *)item)->get_geometry_type() : + (Field::geometry_type)((Item_geometry_func *)item)->get_geometry_type(); } diff --git a/sql/item.h b/sql/item.h index a1704aa6103..9268afaba0c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1304,6 +1304,11 @@ public: int fix_outer_field(THD *thd, Field **field, Item **reference); virtual Item *update_value_transformer(byte *select_arg); void print(String *str); + Field::geometry_type get_geometry_type() + { + DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY); + return field->get_geometry_type(); + } friend class Item_default_value; friend class Item_insert_value; friend class st_select_lex_unit; @@ -2570,6 +2575,7 @@ class Item_type_holder: public Item protected: TYPELIB *enum_set_typelib; enum_field_types fld_type; + Field::geometry_type geometry_type; void get_full_info(Item *item); @@ -2589,6 +2595,7 @@ public: Field *make_field_by_type(TABLE *table); static uint32 display_length(Item *item); static enum_field_types get_real_type(Item *); + Field::geometry_type get_geometry_type() { return geometry_type; }; }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 516d0fcf3e1..ed0c09f0b32 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1755,6 +1755,23 @@ void Item_func_between::fix_length_and_dec() ge_cmp.set_datetime_cmp_func(args, args + 1); le_cmp.set_datetime_cmp_func(args, args + 2); } + else if (args[0]->real_item()->type() == FIELD_ITEM && + thd->lex->sql_command != SQLCOM_CREATE_VIEW && + thd->lex->sql_command != SQLCOM_SHOW_CREATE) + { + Field *field=((Item_field*) (args[0]->real_item()))->field; + if (field->can_be_compared_as_longlong()) + { + /* + The following can't be recoded with || as convert_constant_item + changes the argument + */ + if (convert_constant_item(thd, field,&args[1])) + cmp_type=INT_RESULT; // Works for all types. + if (convert_constant_item(thd, field,&args[2])) + cmp_type=INT_RESULT; // Works for all types. + } + } } diff --git a/sql/item_func.cc b/sql/item_func.cc index 580d19fbd4e..ab4a9c50332 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1957,7 +1957,13 @@ void Item_func_round::fix_length_and_dec() { max_length= args[0]->max_length; decimals= args[0]->decimals; - hybrid_type= REAL_RESULT; + if (args[0]->result_type() == DECIMAL_RESULT) + { + max_length++; + hybrid_type= DECIMAL_RESULT; + } + else + hybrid_type= REAL_RESULT; return; } @@ -3449,6 +3455,7 @@ longlong Item_func_get_lock::val_int() THD *thd=current_thd; User_level_lock *ull; int error; + DBUG_ENTER("Item_func_get_lock::val_int"); /* In slave thread no need to get locks, everything is serialized. Anyway @@ -3458,7 +3465,7 @@ longlong Item_func_get_lock::val_int() it's not guaranteed to be same as on master. */ if (thd->slave_thread) - return 1; + DBUG_RETURN(1); pthread_mutex_lock(&LOCK_user_locks); @@ -3466,8 +3473,10 @@ longlong Item_func_get_lock::val_int() { pthread_mutex_unlock(&LOCK_user_locks); null_value=1; - return 0; + DBUG_RETURN(0); } + DBUG_PRINT("info", ("lock %.*s, thd=%ld", res->length(), res->ptr(), + (long) thd->real_id)); null_value=0; if (thd->ull) @@ -3486,14 +3495,17 @@ longlong Item_func_get_lock::val_int() delete ull; pthread_mutex_unlock(&LOCK_user_locks); null_value=1; // Probably out of memory - return 0; + DBUG_RETURN(0); } ull->thread=thd->real_id; + ull->thread_id=thd->thread_id; thd->ull=ull; pthread_mutex_unlock(&LOCK_user_locks); - return 1; // Got new lock + DBUG_PRINT("info", ("made new lock")); + DBUG_RETURN(1); // Got new lock } ull->count++; + DBUG_PRINT("info", ("ull->count=%d", ull->count)); /* Structure is now initialized. Try to get the lock. @@ -3507,9 +3519,13 @@ longlong Item_func_get_lock::val_int() error= 0; while (ull->locked && !thd->killed) { + DBUG_PRINT("info", ("waiting on lock")); error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime); if (error == ETIMEDOUT || error == ETIME) + { + DBUG_PRINT("info", ("lock wait timeout")); break; + } error= 0; } @@ -3533,6 +3549,7 @@ longlong Item_func_get_lock::val_int() ull->thread_id= thd->thread_id; thd->ull=ull; error=0; + DBUG_PRINT("info", ("got the lock")); } pthread_mutex_unlock(&LOCK_user_locks); @@ -3542,7 +3559,7 @@ longlong Item_func_get_lock::val_int() thd->mysys_var->current_cond= 0; pthread_mutex_unlock(&thd->mysys_var->mutex); - return !error ? 1 : 0; + DBUG_RETURN(!error ? 1 : 0); } @@ -3560,11 +3577,14 @@ longlong Item_func_release_lock::val_int() String *res=args[0]->val_str(&value); User_level_lock *ull; longlong result; + THD *thd=current_thd; + DBUG_ENTER("Item_func_release_lock::val_int"); if (!res || !res->length()) { null_value=1; - return 0; + DBUG_RETURN(0); } + DBUG_PRINT("info", ("lock %.*s", res->length(), res->ptr())); null_value=0; result=0; @@ -3577,19 +3597,20 @@ longlong Item_func_release_lock::val_int() } else { -#ifdef EMBEDDED_LIBRARY - if (ull->locked && pthread_equal(current_thd->real_id,ull->thread)) -#else - if (ull->locked && pthread_equal(pthread_self(),ull->thread)) -#endif + DBUG_PRINT("info", ("ull->locked=%d ull->thread=%ld thd=%ld", + (int) ull->locked, + (long)ull->thread, + (long)thd->real_id)); + if (ull->locked && pthread_equal(thd->real_id,ull->thread)) { + DBUG_PRINT("info", ("release lock")); result=1; // Release is ok item_user_lock_release(ull); - current_thd->ull=0; + thd->ull=0; } } pthread_mutex_unlock(&LOCK_user_locks); - return result; + DBUG_RETURN(result); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index f9a0f715985..33e9b8de823 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3334,7 +3334,7 @@ String *Item_func_uuid::val_str(String *str) *--s=_dig_vec_lower[mac[i] >> 4]; } randominit(&uuid_rand, tmp + (ulong) server_start_time, - tmp + thd->status_var.bytes_sent); + tmp + (ulong) thd->status_var.bytes_sent); set_clock_seq_str(); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3cb7389546b..9029a046b42 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6198,8 +6198,8 @@ struct show_var_st status_vars[]= { {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG}, {"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG}, - {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONG_STATUS}, - {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONG_STATUS}, + {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS}, + {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS}, {"Com_admin_commands", (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS}, {"Com_alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS}, {"Com_alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 2ff5448f3e4..50c45d461e0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -606,8 +606,8 @@ struct system_variables typedef struct system_status_var { - ulong bytes_received; - ulong bytes_sent; + ulonglong bytes_received; + ulonglong bytes_sent; ulong com_other; ulong com_stat[(uint) SQLCOM_END]; ulong created_tmp_disk_tables; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index bf37a3d6d69..228fc8860ae 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -947,20 +947,24 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (values_list.elements == 1 && (!(thd->options & OPTION_WARNINGS) || !thd->cuted_fields)) { - thd->row_count_func= info.copied+info.deleted+info.updated; + thd->row_count_func= info.copied + info.deleted + + ((thd->client_capabilities & CLIENT_FOUND_ROWS) ? + info.touched : info.updated); send_ok(thd, (ulong) thd->row_count_func, id); } else { char buff[160]; + ha_rows updated=((thd->client_capabilities & CLIENT_FOUND_ROWS) ? + info.touched : info.updated); if (ignore) sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, (lock_type == TL_WRITE_DELAYED) ? (ulong) 0 : (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); else sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); - thd->row_count_func= info.copied+info.deleted+info.updated; + (ulong) (info.deleted + updated), (ulong) thd->cuted_fields); + thd->row_count_func= info.copied + info.deleted + updated; ::send_ok(thd, (ulong) thd->row_count_func, id, buff); } thd->abort_on_warning= 0; @@ -1400,23 +1404,18 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) goto before_trg_err; table->file->restore_auto_increment(); - if ((error=table->file->update_row(table->record[1],table->record[0]))) + if ((table->file->table_flags() & HA_PARTIAL_COLUMN_READ) || + compare_record(table, thd->query_id)) { - if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore) + if ((error=table->file->update_row(table->record[1],table->record[0]))) { - goto ok_or_after_trg_err; + if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore) + { + goto ok_or_after_trg_err; + } + goto err; } - goto err; - } - - if (table->next_number_field) - table->file->adjust_next_insert_id_after_explicit_value( - table->next_number_field->val_int()); - info->touched++; - if ((table->file->table_flags() & HA_PARTIAL_COLUMN_READ) || - compare_record(table, thd->query_id)) - { info->updated++; trg_error= (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, @@ -1425,6 +1424,11 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) info->copied++; } + if (table->next_number_field) + table->file->adjust_next_insert_id_after_explicit_value( + table->next_number_field->val_int()); + info->touched++; + goto ok_or_after_trg_err; } else /* DUP_REPLACE */ @@ -2973,7 +2977,9 @@ bool select_insert::send_eof() else sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); - thd->row_count_func= info.copied+info.deleted+info.updated; + thd->row_count_func= info.copied + info.deleted + + ((thd->client_capabilities & CLIENT_FOUND_ROWS) ? + info.touched : info.updated); ::send_ok(thd, (ulong) thd->row_count_func, last_insert_id, buff); DBUG_RETURN(0); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ec7e8a5f997..c9baecd9cf1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5252,7 +5252,17 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, Security_context *sctx= thd->security_ctx; #ifndef NO_EMBEDDED_ACCESS_CHECKS ulong db_access; - bool db_is_pattern= test(want_access & GRANT_ACL); + /* + GRANT command: + In case of database level grant the database name may be a pattern, + in case of table|column level grant the database name can not be a pattern. + We use 'dont_check_global_grants' as a flag to determine + if it's database level grant command + (see SQLCOM_GRANT case, mysql_execute_command() function) and + set db_is_pattern according to 'dont_check_global_grants' value. + */ + bool db_is_pattern= (test(want_access & GRANT_ACL) && + dont_check_global_grants); #endif ulong dummy; DBUG_ENTER("check_access"); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d2f90141fa6..f781d1372ad 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -562,6 +562,8 @@ void set_param_date(Item_param *param, uchar **pos, ulong len) static void set_param_str(Item_param *param, uchar **pos, ulong len) { ulong length= get_param_length(pos, len); + if (length > len) + length= len; param->set_str((const char *)*pos, length); *pos+= length; } @@ -731,6 +733,8 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, if (read_pos >= data_end) DBUG_RETURN(1); param->set_param_func(param, &read_pos, data_end - read_pos); + if (param->state == Item_param::NO_VALUE) + DBUG_RETURN(1); } } res= param->query_val_str(&str); @@ -767,6 +771,8 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array, if (read_pos >= data_end) DBUG_RETURN(1); param->set_param_func(param, &read_pos, data_end - read_pos); + if (param->state == Item_param::NO_VALUE) + DBUG_RETURN(1); } } if (param->convert_str_value(stmt->thd)) @@ -849,6 +855,8 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query) client_param->length ? *client_param->length : client_param->buffer_length); + if (param->state == Item_param::NO_VALUE) + DBUG_RETURN(1); } } if (param->convert_str_value(thd)) @@ -890,6 +898,8 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt, String *query) client_param->length ? *client_param->length : client_param->buffer_length); + if (param->state == Item_param::NO_VALUE) + DBUG_RETURN(1); } } res= param->query_val_str(&str); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d04a6adba15..6bff302f7f8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10147,7 +10147,9 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, /* copy all old rows */ while (!table->file->rnd_next(new_table.record[1])) { - if ((write_err=new_table.file->write_row(new_table.record[1]))) + write_err=new_table.file->write_row(new_table.record[1]); + DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;); + if (write_err) goto err; } /* copy row that filled HEAP table */ @@ -10182,6 +10184,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, delete new_table.file; err2: thd->proc_info=save_proc_info; + table->mem_root= new_table.mem_root; DBUG_RETURN(1); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 16ed20cd479..902b298e423 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1463,6 +1463,8 @@ static bool show_status_array(THD *thd, const char *wild, case SHOW_LONG_CONST: end= int10_to_str(*(long*) value, buff, 10); break; + case SHOW_LONGLONG_STATUS: + value= ((char *) status_var + (ulonglong) value); case SHOW_LONGLONG: end= longlong10_to_str(*(longlong*) value, buff, 10); break; @@ -3158,6 +3160,7 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables, DBUG_ENTER("get_schema_views_record"); char definer[USER_HOST_BUFF_SIZE]; uint definer_len; + bool updatable_view; if (tables->view) { @@ -3195,7 +3198,34 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables, else table->field[4]->store(STRING_WITH_LEN("NONE"), cs); - if (tables->updatable_view) + updatable_view= 0; + if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE) + { + /* + We should use tables->view->select_lex.item_list here and + can not use Field_iterator_view because the view always uses + temporary algorithm during opening for I_S and + TABLE_LIST fields 'field_translation' & 'field_translation_end' + are uninitialized is this case. + */ + List<Item> *fields= &tables->view->select_lex.item_list; + List_iterator<Item> it(*fields); + Item *item; + Item_field *field; + /* + chech that at least one coulmn in view is updatable + */ + while ((item= it++)) + { + if ((field= item->filed_for_view_update()) && field->field && + !field->field->table->pos_in_table_list->schema_table) + { + updatable_view= 1; + break; + } + } + } + if (updatable_view) table->field[5]->store(STRING_WITH_LEN("YES"), cs); else table->field[5]->store(STRING_WITH_LEN("NO"), cs); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 202882d9a48..997864e8e39 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3101,8 +3101,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, alter_info->tablespace_op)); sprintf(new_name_buff,"%s/%s/%s%s",mysql_data_home, db, table_name, reg_ext); unpack_filename(new_name_buff, new_name_buff); - if (lower_case_table_names != 2) - my_casedn_str(files_charset_info, new_name_buff); frm_type= mysql_frm_type(thd, new_name_buff, &table_type); /* Rename a view */ if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d1da36dfa5b..924a8bd6d7d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5820,7 +5820,8 @@ select_derived2: LEX *lex= Lex; lex->derived_tables|= DERIVED_SUBQUERY; if (lex->sql_command == (int)SQLCOM_HA_READ || - lex->sql_command == (int)SQLCOM_KILL) + lex->sql_command == (int)SQLCOM_KILL || + lex->sql_command == (int)SQLCOM_PURGE) { my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; @@ -7275,6 +7276,7 @@ purge: { LEX *lex=Lex; lex->type=0; + lex->sql_command = SQLCOM_PURGE; } purge_options {} ; @@ -7286,7 +7288,6 @@ purge_options: purge_option: TO_SYM TEXT_STRING_sys { - Lex->sql_command = SQLCOM_PURGE; Lex->to_log = $2.str; } | BEFORE_SYM expr @@ -9405,7 +9406,8 @@ subselect_start: { LEX *lex=Lex; if (lex->sql_command == (int)SQLCOM_HA_READ || - lex->sql_command == (int)SQLCOM_KILL) + lex->sql_command == (int)SQLCOM_KILL || + lex->sql_command == (int)SQLCOM_PURGE) { my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; diff --git a/sql/structs.h b/sql/structs.h index de4cc25db9f..28bdd8c1519 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -190,7 +190,8 @@ enum SHOW_TYPE SHOW_NET_COMPRESSION, SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING, SHOW_SLAVE_RETRIED_TRANS, SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_CONST_LONG, SHOW_KEY_CACHE_LONGLONG, - SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS, SHOW_SLAVE_SKIP_ERRORS + SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS, SHOW_SLAVE_SKIP_ERRORS, + SHOW_LONGLONG_STATUS }; enum SHOW_COMP_OPTION { SHOW_OPTION_YES, SHOW_OPTION_NO, SHOW_OPTION_DISABLED}; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index e56dd693287..0985b4d25ec 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15624,6 +15624,63 @@ static void test_bug27876() /* + Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS + flag is set. +*/ + +static void test_bug28505() +{ + my_ulonglong res; + + myquery(mysql_query(mysql, "drop table if exists t1")); + myquery(mysql_query(mysql, "create table t1(f1 int primary key)")); + myquery(mysql_query(mysql, "insert into t1 values(1)")); + myquery(mysql_query(mysql, + "insert into t1 values(1) on duplicate key update f1=1")); + res= mysql_affected_rows(mysql); + DIE_UNLESS(!res); + myquery(mysql_query(mysql, "drop table t1")); +} + + +/* + Bug#28934: server crash when receiving malformed com_execute packets +*/ + +static void test_bug28934() +{ + my_bool error= 0; + MYSQL_BIND bind[5]; + MYSQL_STMT *stmt; + int cnt; + + myquery(mysql_query(mysql, "drop table if exists t1")); + myquery(mysql_query(mysql, "create table t1(id int)")); + + myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)")); + stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)"); + check_stmt(stmt); + + memset (&bind, 0, sizeof (bind)); + for (cnt= 0; cnt < 5; cnt++) + { + bind[cnt].buffer_type= MYSQL_TYPE_LONG; + bind[cnt].buffer= (char*)&cnt; + bind[cnt].buffer_length= 0; + } + myquery(mysql_stmt_bind_param(stmt, bind)); + + stmt->param_count=2; + error= mysql_stmt_execute(stmt); + DIE_UNLESS(error != 0); + myerror(NULL); + mysql_stmt_close(stmt); + + myquery(mysql_query(mysql, "drop table t1")); +} + + +/* Read and parse arguments and MySQL options from my.cnf */ @@ -15904,6 +15961,8 @@ static struct my_tests_st my_tests[]= { { "test_bug21635", test_bug21635 }, { "test_bug24179", test_bug24179 }, { "test_bug27876", test_bug27876 }, + { "test_bug28505", test_bug28505 }, + { "test_bug28934", test_bug28934 }, { 0, 0 } }; |