diff --git a/.bzrignore b/.bzrignore index 4325a9177fa..c4ae17ed95e 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1,3 +1,5 @@ +*.Plo +*.Po *.a *.bb *.bbg @@ -11,6 +13,8 @@ *.reject *.spec */*_pure_*warnings +*/.deps +*/.libs/* */.pure *~ .*.swp @@ -336,6 +340,7 @@ isam/test2 isam/test3 libmysql/*.c libmysql/conf_to_src +libmysql/libmysql.ver libmysql/my_static.h libmysql/my_time.c libmysql/mysys_priv.h @@ -443,6 +448,7 @@ libmysqld/sql_insert.cc libmysqld/sql_lex.cc libmysqld/sql_list.cc libmysqld/sql_load.cc +libmysqld/sql_locale.cc libmysqld/sql_manager.cc libmysqld/sql_map.cc libmysqld/sql_olap.cc @@ -519,6 +525,7 @@ mysql-4.1.8-win-src.zip mysql-max-4.0.2-alpha-pc-linux-gnu-i686.tar.gz mysql-test/gmon.out mysql-test/install_test_db +mysql-test/mtr mysql-test/mysql-test-run mysql-test/mysql-test-run.log mysql-test/mysql_test_run_new @@ -1057,6 +1064,3 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl -libmysql/libmysql.ver -libmysqld/sql_locale.cc -mysql-test/mtr diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index bd2d162d100..0edb3ac1d5d 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -16,7 +16,7 @@ /* Functions to compressed records */ -#include "myisamdef.h" +#include "fulltext.h" #define IS_CHAR ((uint) 32768) /* Bit if char (not offset) in tree */ @@ -228,11 +228,19 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) { for (i=0 ; i < share->base.keys ; i++) { - share->keyinfo[i].keylength+=(uint16) diff_length; - share->keyinfo[i].minlength+=(uint16) diff_length; - share->keyinfo[i].maxlength+=(uint16) diff_length; - share->keyinfo[i].seg[share->keyinfo[i].keysegs].length= - (uint16) rec_reflength; + MI_KEYDEF *keyinfo= &share->keyinfo[i]; + keyinfo->keylength+= (uint16) diff_length; + keyinfo->minlength+= (uint16) diff_length; + keyinfo->maxlength+= (uint16) diff_length; + keyinfo->seg[keyinfo->flag & HA_FULLTEXT ? + FT_SEGS : keyinfo->keysegs].length= (uint16) rec_reflength; + } + if (share->ft2_keyinfo.seg) + { + MI_KEYDEF *ft2_keyinfo= &share->ft2_keyinfo; + ft2_keyinfo->keylength+= (uint16) diff_length; + ft2_keyinfo->minlength+= (uint16) diff_length; + ft2_keyinfo->maxlength+= (uint16) diff_length; } } diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c index 98e1a0a9a26..b2d40288645 100644 --- a/myisam/mi_rkey.c +++ b/myisam/mi_rkey.c @@ -93,32 +93,45 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len, myisam_read_vec[search_flag], info->s->state.key_root[inx])) { /* - If we are searching for an exact key (including the data pointer) - and this was added by an concurrent insert, - then the result is "key not found". + If we searching for a partial key (or using >, >=, < or <=) and + the data is outside of the data file, we need to continue searching + for the first key inside the data file */ - if ((search_flag == HA_READ_KEY_EXACT) && - (info->lastpos >= info->state->data_file_length)) + if (info->lastpos >= info->state->data_file_length && + (search_flag != HA_READ_KEY_EXACT || + last_used_keyseg != keyinfo->seg + keyinfo->keysegs)) { - my_errno= HA_ERR_KEY_NOT_FOUND; - info->lastpos= HA_OFFSET_ERROR; - } - else while (info->lastpos >= info->state->data_file_length) - { - /* - Skip rows that are inserted by other threads since we got a lock - Note that this can only happen if we are not searching after an - exact key, because the keys are sorted according to position - */ - if (_mi_search_next(info, keyinfo, info->lastkey, - info->lastkey_length, - myisam_readnext_vec[search_flag], - info->s->state.key_root[inx])) - break; + do + { + uint not_used[2]; + /* + Skip rows that are inserted by other threads since we got a lock + Note that this can only happen if we are not searching after an + full length exact key, because the keys are sorted + according to position + */ + if (_mi_search_next(info, keyinfo, info->lastkey, + info->lastkey_length, + myisam_readnext_vec[search_flag], + info->s->state.key_root[inx])) + break; + /* + Check that the found key does still match the search. + _mi_search_next() delivers the next key regardless of its + value. + */ + if (search_flag == HA_READ_KEY_EXACT && + ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, use_key_length, + SEARCH_FIND, not_used)) + { + my_errno= HA_ERR_KEY_NOT_FOUND; + info->lastpos= HA_OFFSET_ERROR; + break; + } + } while (info->lastpos >= info->state->data_file_length); } } } - if (share->concurrent_insert) rw_unlock(&share->key_root_lock[inx]); diff --git a/myisam/mi_test_all.res b/myisam/mi_test_all.res index 94355bf1aa2..5c0d05cc977 100644 --- a/myisam/mi_test_all.res +++ b/myisam/mi_test_all.res @@ -5,46 +5,46 @@ myisamchk: MyISAM file test2 myisamchk: warning: Datafile is almost full, 65532 of 65534 used MyISAM-table 'test2' is usable but should be fixed Commands Used count Errors Recover errors -open 17 0 0 -write 850 0 0 -update 85 0 0 -delete 850 0 0 -close 17 0 0 -extra 102 0 0 -Total 1921 0 0 +open 7 0 0 +write 350 0 0 +update 35 0 0 +delete 350 0 0 +close 7 0 0 +extra 42 0 0 +Total 791 0 0 Commands Used count Errors Recover errors -open 18 0 0 -write 900 0 0 -update 90 0 0 -delete 900 0 0 -close 18 0 0 -extra 108 0 0 -Total 2034 0 0 +open 8 0 0 +write 400 0 0 +update 40 0 0 +delete 400 0 0 +close 8 0 0 +extra 48 0 0 +Total 904 0 0 -real 0m1.054s -user 0m0.410s -sys 0m0.640s +real 0m0.221s +user 0m0.120s +sys 0m0.100s -real 0m1.077s -user 0m0.550s -sys 0m0.530s +real 0m0.222s +user 0m0.140s +sys 0m0.084s -real 0m1.100s -user 0m0.420s -sys 0m0.680s +real 0m0.232s +user 0m0.112s +sys 0m0.120s -real 0m0.783s -user 0m0.590s -sys 0m0.200s +real 0m0.163s +user 0m0.116s +sys 0m0.036s -real 0m0.764s -user 0m0.560s -sys 0m0.210s +real 0m0.159s +user 0m0.136s +sys 0m0.020s -real 0m0.699s -user 0m0.570s -sys 0m0.130s +real 0m0.147s +user 0m0.132s +sys 0m0.016s -real 0m0.991s -user 0m0.630s -sys 0m0.350s +real 0m0.211s +user 0m0.124s +sys 0m0.088s diff --git a/myisam/mi_test_all.sh b/myisam/mi_test_all.sh index 07e71d65675..c1fb12d7c3b 100755 --- a/myisam/mi_test_all.sh +++ b/myisam/mi_test_all.sh @@ -79,7 +79,8 @@ myisamchk$suffix -se test1 # check of myisampack / myisamchk myisampack$suffix --force -s test1 -myisamchk$suffix -es test1 +# Ignore error for index file +myisamchk$suffix -es test1 2>&1 >& /dev/null myisamchk$suffix -rqs test1 myisamchk$suffix -es test1 myisamchk$suffix -rs test1 diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index 411cd52b4ca..cb632fcd6c8 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -172,3 +172,7 @@ a 0 2 DROP TABLE t1; +create table t1 (a int); +delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5; +delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5; +drop table t1; diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 2c79b8f8ab1..db0125b7d4f 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -559,14 +559,14 @@ COUNT(*) GROUP_CONCAT(DISTINCT t2.somename SEPARATOR ' |') DROP TABLE t1,t2; select * from (select group_concat('c') from DUAL) t; group_concat('c') -NULL +c create table t1 ( a int not null default 0); select * from (select group_concat(a) from t1) t2; group_concat(a) NULL select group_concat('x') UNION ALL select 1; group_concat('x') -NULL +x 1 drop table t1; CREATE TABLE t1 (id int, a varchar(9)); diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 932ef133087..04f6ebe6398 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -794,7 +794,7 @@ min(7) NULL select min(7) from DUAL; min(7) -NULL +7 explain select min(7) from t2m join t1m; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away @@ -809,7 +809,7 @@ max(7) NULL select max(7) from DUAL; max(7) -NULL +7 explain select max(7) from t2m join t1m; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away @@ -848,7 +848,7 @@ min(7) NULL select min(7) from DUAL; min(7) -NULL +7 explain select min(7) from t2i join t1i; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2i ALL NULL NULL NULL NULL 1 @@ -864,7 +864,7 @@ max(7) NULL select max(7) from DUAL; max(7) -NULL +7 explain select max(7) from t2i join t1i; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2i ALL NULL NULL NULL NULL 1 @@ -942,3 +942,19 @@ EXPLAIN SELECT MAX(b) FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1),(1,2),(2,3); +SELECT (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a; +(SELECT COUNT(DISTINCT t1.b)) +1 +1 +SELECT (SELECT COUNT(DISTINCT 12)) FROM t1 GROUP BY t1.a; +(SELECT COUNT(DISTINCT 12)) +1 +1 +SELECT AVG(2), BIT_AND(2), BIT_OR(2), BIT_XOR(2), COUNT(*), COUNT(12), +COUNT(DISTINCT 12), MIN(2),MAX(2),STD(2), VARIANCE(2),SUM(2), +GROUP_CONCAT(2),GROUP_CONCAT(DISTINCT 2); +AVG(2) BIT_AND(2) BIT_OR(2) BIT_XOR(2) COUNT(*) COUNT(12) COUNT(DISTINCT 12) MIN(2) MAX(2) STD(2) VARIANCE(2) SUM(2) GROUP_CONCAT(2) GROUP_CONCAT(DISTINCT 2) +2.0000 2 2 2 1 1 1 2 2 0.0000 0.0000 2 2 2 +DROP TABLE t1; diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 47a0f83802c..97dd8e243b2 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -646,37 +646,36 @@ drop table t1; create table t1(f1 date, f2 time, f3 datetime); insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01"); insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02"); -select f1 from t1 where f1 between "2006-1-1" and 20060101; +select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date); f1 2006-01-01 -select f1 from t1 where f1 between "2006-1-1" and "2006.1.1"; +select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date); f1 2006-01-01 -select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1"; +select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as date); f1 2006-01-01 -select f2 from t1 where f2 between "12:1:2" and "12:2:2"; +select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time); f2 12:01:02 -select f2 from t1 where time(f2) between "12:1:2" and "12:2:2"; +select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as time); f2 12:01:02 -select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2"; +select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime); f3 2006-01-01 12:01:01 -select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2"; +select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime); f3 2006-01-01 12:01:01 -select f1 from t1 where "2006-1-1" between f1 and f3; +select f1 from t1 where cast("2006-1-1" as date) between f1 and f3; f1 2006-01-01 -select f1 from t1 where "2006-1-1" between date(f1) and date(f3); +select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3); f1 2006-01-01 -select f1 from t1 where "2006-1-1" between f1 and 'zzz'; +select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz'; f1 -Warnings: -Warning 1292 Truncated incorrect date value: 'zzz' +2006-01-01 select f1 from t1 where makedate(2006,1) between date(f1) and date(f3); f1 2006-01-01 diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result index 9e674cc4aae..c41aab29853 100644 --- a/mysql-test/r/insert_update.result +++ b/mysql-test/r/insert_update.result @@ -63,9 +63,9 @@ Warnings: Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c`,values(test.t1.a) AS `VALUES(a)` from test.t1 explain extended select * from t1 where values(a); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where Warnings: -Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c` from test.t1 +Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c` from test.t1 where values(test.t1.a) DROP TABLE t1; create table t1(a int primary key, b int); insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5); @@ -197,3 +197,25 @@ PRIMARY KEY (a) ) ENGINE=MyISAM; INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ; DROP TABLE t1; +CREATE TABLE t1 +( +a BIGINT UNSIGNED, +b BIGINT UNSIGNED, +PRIMARY KEY (a) +); +INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b = +IF(VALUES(b) > t1.b, VALUES(b), t1.b); +SELECT * FROM t1; +a b +45 1 +INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b = +IF(VALUES(b) > t1.b, VALUES(b), t1.b); +SELECT * FROM t1; +a b +45 2 +INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b = +IF(VALUES(b) > t1.b, VALUES(b), t1.b); +SELECT * FROM t1; +a b +45 2 +DROP TABLE t1; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index d7c9ba19a8a..05f72b22ed1 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -508,6 +508,34 @@ select c1 from t1 order by c1 limit 1; c1 a drop table t1; +create table t1 (a int not null, primary key(a)); +create table t2 (a int not null, b int not null, primary key(a,b)); +insert into t1 values (1),(2),(3),(4),(5),(6); +insert into t2 values (1,1),(2,1); +lock tables t1 read local, t2 read local; +select straight_join * from t1,t2 force index (primary) where t1.a=t2.a; +a a b +1 1 1 +2 2 1 +insert into t2 values(2,0); +select straight_join * from t1,t2 force index (primary) where t1.a=t2.a; +a a b +1 1 1 +2 2 1 +drop table t1,t2; +CREATE TABLE t1 (c1 varchar(250) NOT NULL); +CREATE TABLE t2 (c1 varchar(250) NOT NULL, PRIMARY KEY (c1)); +INSERT INTO t1 VALUES ('test000001'), ('test000002'), ('test000003'); +INSERT INTO t2 VALUES ('test000002'), ('test000003'), ('test000004'); +LOCK TABLES t1 READ LOCAL, t2 READ LOCAL; +SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2 +WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1; +t1c1 t2c1 +INSERT INTO t2 VALUES ('test000001'), ('test000005'); +SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2 +WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1; +t1c1 t2c1 +DROP TABLE t1,t2; CREATE TABLE t1 (`a` int(11) NOT NULL default '0', `b` int(11) NOT NULL default '0', UNIQUE KEY `a` USING RTREE (`a`,`b`)) ENGINE=MyISAM; Got one of the listed errors create table t1 (a int, b varchar(200), c text not null) checksum=1; diff --git a/mysql-test/r/rpl_insert_id.result b/mysql-test/r/rpl_insert_id.result index e683ea2fb39..fbdc9dc06cf 100644 --- a/mysql-test/r/rpl_insert_id.result +++ b/mysql-test/r/rpl_insert_id.result @@ -1,9 +1,20 @@ +# +# Setup +# stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +use test; +drop table if exists t1, t2, t3; +# +# See if queries that use both auto_increment and LAST_INSERT_ID() +# are replicated well +# +# We also check how the foreign_key_check variable is replicated +# create table t1(a int auto_increment, key(a)); create table t2(b int auto_increment, c int, key(b)); insert into t1 values (1),(2),(3); @@ -38,6 +49,9 @@ select * from t2; b c 5 0 6 11 +# +# check if INSERT SELECT in auto_increment is well replicated (bug #490) +# drop table t2; drop table t1; create table t1(a int auto_increment, key(a)); @@ -68,11 +82,18 @@ b c 9 13 drop table t1; drop table t2; +# +# Bug#8412: Error codes reported in binary log for CHARACTER SET, +# FOREIGN_KEY_CHECKS +# SET TIMESTAMP=1000000000; CREATE TABLE t1 ( a INT UNIQUE ); SET FOREIGN_KEY_CHECKS=0; INSERT INTO t1 VALUES (1),(1); ERROR 23000: Duplicate entry '1' for key 1 +# +# Bug#14553: NULL in WHERE resets LAST_INSERT_ID +# drop table t1; create table t1(a int auto_increment, key(a)); create table t2(a int); @@ -87,3 +108,6 @@ a 1 drop table t1; drop table t2; +# +# End of 4.1 tests +# diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result index 5c3360b0f66..c0a7a0a5b00 100644 --- a/mysql-test/r/rpl_max_relay_size.result +++ b/mysql-test/r/rpl_max_relay_size.result @@ -5,9 +5,15 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; stop slave; +# +# Generate a big enough master's binlog to cause relay log rotations +# create table t1 (a int); drop table t1; reset slave; +# +# Test 1 +# set global max_binlog_size=8192; set global max_relay_log_size=8192-1; select @@global.max_relay_log_size; @@ -15,47 +21,248 @@ select @@global.max_relay_log_size; 4096 start slave; show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000014 1221 master-bin.000001 Yes Yes 0 0 50477 1221 None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 50477 +Relay_Log_File slave-relay-bin.000014 +Relay_Log_Pos 1221 +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 50477 +Relay_Log_Space 1221 +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +# +# Test 2 +# stop slave; reset slave; set global max_relay_log_size=(5*4096); select @@global.max_relay_log_size; -@@global.max_relay_log_size -20480 +@@global.max_relay_log_size 20480 start slave; show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000004 9457 master-bin.000001 Yes Yes 0 0 50477 9457 None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 50477 +Relay_Log_File slave-relay-bin.000004 +Relay_Log_Pos 9457 +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 50477 +Relay_Log_Space 9457 +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +# +# Test 3: max_relay_log_size = 0 +# stop slave; reset slave; set global max_relay_log_size=0; select @@global.max_relay_log_size; -@@global.max_relay_log_size -0 +@@global.max_relay_log_size 0 start slave; show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000008 1283 master-bin.000001 Yes Yes 0 0 50477 1283 None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 50477 +Relay_Log_File slave-relay-bin.000008 +Relay_Log_Pos 1283 +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 50477 +Relay_Log_Space 1283 +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +# +# Test 4: Tests below are mainly to ensure that we have not coded with wrong assumptions +# stop slave; reset slave; flush logs; show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File +Read_Master_Log_Pos 4 +Relay_Log_File slave-relay-bin.000001 +Relay_Log_Pos 4 +Relay_Master_Log_File +Slave_IO_Running No +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 0 +Relay_Log_Space 4 +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +# +# Test 5 +# reset slave; start slave; flush logs; create table t1 (a int); show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50535 slave-relay-bin.000009 62 master-bin.000001 Yes Yes 0 0 50535 62 None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 50535 +Relay_Log_File slave-relay-bin.000009 +Relay_Log_Pos 62 +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 50535 +Relay_Log_Space 62 +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +# +# Test 6: one more rotation, to be sure Relay_Log_Space is correctly updated +# flush logs; drop table t1; show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 50583 slave-relay-bin.000010 52 master-bin.000001 Yes Yes 0 0 50583 52 None 0 No # +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 50583 +Relay_Log_File slave-relay-bin.000010 +Relay_Log_Pos 52 +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 50583 +Relay_Log_Space 52 +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # flush logs; show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000002 4 +File master-bin.000002 +Position 4 +Binlog_Do_DB +Binlog_Ignore_DB diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index f5abc4ed42a..ba4de7f6406 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1001,7 +1001,7 @@ INSERT INTO t1 VALUES (1); UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i)); select * from t1; i -1 +2 drop table t1; CREATE TABLE t1 (a int(1)); EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1; @@ -1193,7 +1193,7 @@ UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t); ERROR 42S02: Unknown table 't' in field list select * from t1; i -1 +3 drop table t1; CREATE TABLE t1 ( id int(11) default NULL @@ -2917,3 +2917,32 @@ retailerID statusID changed 0048 1 2006-01-06 12:37:50 0059 1 2006-01-06 12:37:50 drop table t1; +create table t1(a int, primary key (a)); +insert into t1 values (10); +create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); +insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); +explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r +ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' +ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 +1 PRIMARY r const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY t2 range b b 38 NULL 2 Using where +SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r +ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' +ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; +a a b +10 3 35989 +explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r +ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' +ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 +1 PRIMARY r const PRIMARY PRIMARY 4 const 1 +2 DEPENDENT SUBQUERY t2 range b b 38 NULL 2 Using where +SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r +ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' +ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; +a a b +10 1 359 +drop table t1,t2; diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 3428b5969d9..99e9adf84ca 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -27,12 +27,12 @@ INSERT INTO t1 VALUES ( "2000-1-2" ); INSERT INTO t1 VALUES ( "2000-1-3" ); INSERT INTO t1 VALUES ( "2000-1-4" ); INSERT INTO t1 VALUES ( "2000-1-5" ); -SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4"; +SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND cast("2000-1-4" as date); datum 2000-01-02 2000-01-03 2000-01-04 -SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY; +SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND datum - INTERVAL 100 DAY; datum DROP TABLE t1; CREATE TABLE t1 ( @@ -104,3 +104,9 @@ SELECT * FROM t1; y 0000 DROP TABLE t1; +create table t1(start_date date, end_date date); +insert into t1 values ('2000-01-01','2000-01-02'); +select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and end_date; +1 +1 +drop table t1; diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index 98e4c4e35fa..d4eb01cab23 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -153,4 +153,14 @@ DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a LIMIT 1; SELECT * FROM t1; DROP TABLE t1; +# +# Bug #21392: multi-table delete with alias table name fails with +# 1003: Incorrect table name +# + +create table t1 (a int); +delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5; +delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index f8a3ed0f25e..18cb5d0a430 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -617,4 +617,18 @@ SELECT MAX(b) FROM t1; EXPLAIN SELECT MAX(b) FROM t1; DROP TABLE t1; +# +# Bug #16792 query with subselect, join, and group not returning proper values +# +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1,1),(1,2),(2,3); + +SELECT (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a; +SELECT (SELECT COUNT(DISTINCT 12)) FROM t1 GROUP BY t1.a; +# an attempt to test all aggregate function with no table. +SELECT AVG(2), BIT_AND(2), BIT_OR(2), BIT_XOR(2), COUNT(*), COUNT(12), + COUNT(DISTINCT 12), MIN(2),MAX(2),STD(2), VARIANCE(2),SUM(2), + GROUP_CONCAT(2),GROUP_CONCAT(DISTINCT 2); +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 472f3d81d2b..04bfc741d1c 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -341,20 +341,20 @@ drop table t1; # # Bug#16377 result of DATE/TIME functions were compared as strings which # can lead to a wrong result. -# +# Now wrong dates should be compared only with CAST() create table t1(f1 date, f2 time, f3 datetime); insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01"); insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02"); -select f1 from t1 where f1 between "2006-1-1" and 20060101; -select f1 from t1 where f1 between "2006-1-1" and "2006.1.1"; -select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1"; -select f2 from t1 where f2 between "12:1:2" and "12:2:2"; -select f2 from t1 where time(f2) between "12:1:2" and "12:2:2"; -select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2"; -select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2"; -select f1 from t1 where "2006-1-1" between f1 and f3; -select f1 from t1 where "2006-1-1" between date(f1) and date(f3); -select f1 from t1 where "2006-1-1" between f1 and 'zzz'; +select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date); +select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date); +select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as date); +select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time); +select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as time); +select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime); +select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime); +select f1 from t1 where cast("2006-1-1" as date) between f1 and f3; +select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3); +select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz'; select f1 from t1 where makedate(2006,1) between date(f1) and date(f3); select f1 from t1 where makedate(2006,2) between date(f1) and date(f3); drop table t1; diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test index 8038bd7bfe7..56885a555fd 100644 --- a/mysql-test/t/insert_update.test +++ b/mysql-test/t/insert_update.test @@ -115,4 +115,27 @@ INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ; DROP TABLE t1; +# +# Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES +# + + # End of 4.1 tests +CREATE TABLE t1 +( + a BIGINT UNSIGNED, + b BIGINT UNSIGNED, + PRIMARY KEY (a) +); + +INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b = + IF(VALUES(b) > t1.b, VALUES(b), t1.b); +SELECT * FROM t1; +INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b = + IF(VALUES(b) > t1.b, VALUES(b), t1.b); +SELECT * FROM t1; +INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b = + IF(VALUES(b) > t1.b, VALUES(b), t1.b); +SELECT * FROM t1; + +DROP TABLE t1; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 11d0693b511..a62a6487882 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -485,6 +485,42 @@ insert into t1 values ('a'), ('b'); select c1 from t1 order by c1 limit 1; drop table t1; +# +# Bug #14400 Join could miss concurrently inserted row +# +# Partial key. +create table t1 (a int not null, primary key(a)); +create table t2 (a int not null, b int not null, primary key(a,b)); +insert into t1 values (1),(2),(3),(4),(5),(6); +insert into t2 values (1,1),(2,1); +lock tables t1 read local, t2 read local; +select straight_join * from t1,t2 force index (primary) where t1.a=t2.a; +connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock); +insert into t2 values(2,0); +disconnect root; +connection default; +select straight_join * from t1,t2 force index (primary) where t1.a=t2.a; +drop table t1,t2; +# +# Full key. +CREATE TABLE t1 (c1 varchar(250) NOT NULL); +CREATE TABLE t2 (c1 varchar(250) NOT NULL, PRIMARY KEY (c1)); +INSERT INTO t1 VALUES ('test000001'), ('test000002'), ('test000003'); +INSERT INTO t2 VALUES ('test000002'), ('test000003'), ('test000004'); +LOCK TABLES t1 READ LOCAL, t2 READ LOCAL; +SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2 + WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1; +connect (con1,localhost,root,,); +connection con1; +INSERT INTO t2 VALUES ('test000001'), ('test000005'); +disconnect con1; +connection default; +SELECT t1.c1 AS t1c1, t2.c1 AS t2c1 FROM t1, t2 + WHERE t1.c1 = t2.c1 HAVING t1c1 != t2c1; +DROP TABLE t1,t2; + +# End of 4.0 tests + # # Test RTREE index # diff --git a/mysql-test/t/rpl_insert_id.test b/mysql-test/t/rpl_insert_id.test index 766afad9e47..327094a1394 100644 --- a/mysql-test/t/rpl_insert_id.test +++ b/mysql-test/t/rpl_insert_id.test @@ -1,10 +1,21 @@ -# See if queries that use both auto_increment and LAST_INSERT_ID() -# are replicated well - -# We also check how the foreign_key_check variable is replicated +--echo # +--echo # Setup +--echo # source include/master-slave.inc; source include/have_innodb.inc; +use test; +--disable_warnings +drop table if exists t1, t2, t3; +--enable_warnings + +--echo # +--echo # See if queries that use both auto_increment and LAST_INSERT_ID() +--echo # are replicated well +--echo # +--echo # We also check how the foreign_key_check variable is replicated +--echo # + connection master; create table t1(a int auto_increment, key(a)); create table t2(b int auto_increment, c int, key(b)); @@ -39,7 +50,9 @@ select * from t1; select * from t2; connection master; -# check if INSERT SELECT in auto_increment is well replicated (bug #490) +--echo # +--echo # check if INSERT SELECT in auto_increment is well replicated (bug #490) +--echo # drop table t2; drop table t1; @@ -62,10 +75,11 @@ save_master_pos; connection slave; sync_with_master; -# -# Bug#8412: Error codes reported in binary log for CHARACTER SET, -# FOREIGN_KEY_CHECKS -# +--echo # +--echo # Bug#8412: Error codes reported in binary log for CHARACTER SET, +--echo # FOREIGN_KEY_CHECKS +--echo # + connection master; SET TIMESTAMP=1000000000; CREATE TABLE t1 ( a INT UNIQUE ); @@ -74,9 +88,10 @@ SET FOREIGN_KEY_CHECKS=0; INSERT INTO t1 VALUES (1),(1); sync_slave_with_master; -# -# Bug#14553: NULL in WHERE resets LAST_INSERT_ID -# +--echo # +--echo # Bug#14553: NULL in WHERE resets LAST_INSERT_ID +--echo # + connection master; drop table t1; create table t1(a int auto_increment, key(a)); @@ -92,4 +107,7 @@ connection master; drop table t1; drop table t2; sync_slave_with_master; -# End of 4.1 tests + +--echo # +--echo # End of 4.1 tests +--echo # diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test index c01041d7eee..63d7ef35413 100644 --- a/mysql-test/t/rpl_max_relay_size.test +++ b/mysql-test/t/rpl_max_relay_size.test @@ -7,7 +7,11 @@ source include/master-slave.inc; connection slave; stop slave; connection master; -# Generate a big enough master's binlog to cause relay log rotations + +--echo # +--echo # Generate a big enough master's binlog to cause relay log rotations +--echo # + create table t1 (a int); let $1=800; disable_query_log; @@ -23,6 +27,11 @@ drop table t1; save_master_pos; connection slave; reset slave; + +--echo # +--echo # Test 1 +--echo # + set global max_binlog_size=8192; set global max_relay_log_size=8192-1; # mapped to 4096 select @@global.max_relay_log_size; @@ -30,7 +39,13 @@ start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # +--vertical_results show slave status; + +--echo # +--echo # Test 2 +--echo # + stop slave; reset slave; set global max_relay_log_size=(5*4096); @@ -39,7 +54,13 @@ start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # +--vertical_results show slave status; + +--echo # +--echo # Test 3: max_relay_log_size = 0 +--echo # + stop slave; reset slave; set global max_relay_log_size=0; @@ -48,9 +69,12 @@ start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # +--vertical_results show slave status; -# Tests below are mainly to ensure that we have not coded with wrong assumptions +--echo # +--echo # Test 4: Tests below are mainly to ensure that we have not coded with wrong assumptions +--echo # stop slave; reset slave; @@ -59,8 +83,13 @@ reset slave; flush logs; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # +--vertical_results show slave status; +--echo # +--echo # Test 5 +--echo # + reset slave; start slave; sync_with_master; @@ -75,8 +104,13 @@ connection slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # +--vertical_results show slave status; -# one more rotation, to be sure Relay_Log_Space is correctly updated + +--echo # +--echo # Test 6: one more rotation, to be sure Relay_Log_Space is correctly updated +--echo # + flush logs; connection master; drop table t1; @@ -85,6 +119,7 @@ connection slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT --replace_column 1 # 33 # +--vertical_results show slave status; connection master; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 10dfb788c10..1018b5de005 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1885,4 +1885,30 @@ select * from t1 r1 group by r2.retailerId); drop table t1; +# +# Bug #21180: Subselect with index for both WHERE and ORDER BY +# produces empty result +# +create table t1(a int, primary key (a)); +insert into t1 values (10); + +create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); +insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); + +explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r + ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' + ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; +SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r + ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' + ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; + +explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r + ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' + ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; +SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r + ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' + ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; + +drop table t1,t2; + # End of 4.1 tests diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 78bdd9b8a80..c6050753943 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -36,8 +36,8 @@ INSERT INTO t1 VALUES ( "2000-1-2" ); INSERT INTO t1 VALUES ( "2000-1-3" ); INSERT INTO t1 VALUES ( "2000-1-4" ); INSERT INTO t1 VALUES ( "2000-1-5" ); -SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4"; -SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY; +SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND cast("2000-1-4" as date); +SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND datum - INTERVAL 100 DAY; DROP TABLE t1; # @@ -115,4 +115,11 @@ INSERT INTO t1 VALUES ('abc'); SELECT * FROM t1; DROP TABLE t1; +# +# Bug#21677: Wrong result when comparing a DATE and a DATETIME in BETWEEN +# +create table t1(start_date date, end_date date); +insert into t1 values ('2000-01-01','2000-01-02'); +select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and end_date; +drop table t1; # End of 4.1 tests diff --git a/scripts/mysql_config.sh b/scripts/mysql_config.sh index 84ff518c381..1fcad16affb 100644 --- a/scripts/mysql_config.sh +++ b/scripts/mysql_config.sh @@ -97,11 +97,11 @@ port='@MYSQL_TCP_PORT@' ldflags='@LDFLAGS@' # Create options -# We intentionally add a space to the beginning of lib strings, simplifies replace later +# We intentionally add a space to the beginning and end of lib strings, simplifies replace later libs=" $ldflags -L$pkglibdir -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@" -libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@" -libs_r=" $ldflags -L$pkglibdir -lmysqlclient_r @ZLIB_DEPS@ @LIBS@ @openssl_libs@" -embedded_libs=" $ldflags -L$pkglibdir -lmysqld @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @innodb_system_libs@" +libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ " +libs_r=" $ldflags -L$pkglibdir -lmysqlclient_r @ZLIB_DEPS@ @LIBS@ @openssl_libs@ " +embedded_libs=" $ldflags -L$pkglibdir -lmysqld @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @innodb_system_libs@ " cflags="-I$pkgincludedir @CFLAGS@ " #note: end space! include="-I$pkgincludedir" @@ -111,8 +111,9 @@ include="-I$pkgincludedir" # and -xstrconst to make --cflags usable for Sun Forte C++ for remove in DDBUG_OFF DSAFEMALLOC USAFEMALLOC DSAFE_MUTEX \ DPEDANTIC_SAFEMALLOC DUNIV_MUST_NOT_INLINE DFORCE_INIT_OF_VARS \ - DEXTRA_DEBUG DHAVE_purify 'O[0-9]' 'W[-A-Za-z]*' \ - Xa xstrconst "xc99=none" + DEXTRA_DEBUG DHAVE_purify O 'O[0-9]' 'xO[0-9]' 'W[-A-Za-z]*' \ + Xa xstrconst "xc99=none" \ + unroll2 ip mp restrict do # The first option we might strip will always have a space before it because # we set -I$pkgincludedir as the first option @@ -121,7 +122,7 @@ done cflags=`echo "$cflags"|sed -e 's/ *\$//'` # Same for --libs(_r) -for remove in lmtmalloc +for remove in lmtmalloc static-libcxa i-static do # We know the strings starts with a space libs=`echo "$libs"|sed -e "s/ -$remove */ /g"` diff --git a/sql/item.h b/sql/item.h index 3eab695cb5e..ad8bea663f1 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1241,7 +1241,11 @@ public: { return Item_field::save_in_field(field_arg, no_conversions); } - table_map used_tables() const { return (table_map)0L; } + /* + We use RAND_TABLE_BIT to prevent Item_insert_value from + being treated as a constant and precalculated before execution + */ + table_map used_tables() const { return RAND_TABLE_BIT; } bool walk(Item_processor processor, byte *args) { diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index a32bd0a7337..6b6996160a1 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -75,119 +75,14 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems) This function aggregates result types from the array of items. Found type supposed to be used later for comparison of values of these items. Aggregation itself is performed by the item_cmp_type() function. - - NOTES - Aggregation rules: - If there are DATE/TIME fields/functions in the list and no string - fields/functions in the list then: - The INT_RESULT type will be used for aggregation instead of original - result type of any DATE/TIME field/function in the list - All constant items in the list will be converted to a DATE/TIME using - found field or result field of found function. - - Implementation notes: - The code is equivalent to: - 1. Check the list for presence of a STRING field/function. - Collect the is_const flag. - 2. Get a Field* object to use for type coercion - 3. Perform type conversion. - 1 and 2 are implemented in 2 loops. The first searches for a DATE/TIME - field/function and checks presence of a STRING field/function. - The second loop works only if a DATE/TIME field/function is found. - It checks presence of a STRING field/function in the rest of the list. - - TODO - 1) The current implementation can produce false comparison results for - expressions like: - date_time_field BETWEEN string_field_with_dates AND string_constant - if the string_constant will omit some of leading zeroes. - In order to fully implement correct comparison of DATE/TIME the new - DATETIME_RESULT result type should be introduced and agg_cmp_type() - should return the DATE/TIME field used for the conversion. Later - this field can be used by comparison functions like Item_func_between to - convert string values to ints on the fly and thus return correct results. - This modification will affect functions BETWEEN, IN and CASE. - - 2) If in the list a DATE field/function and a DATETIME field/function - are present in the list then the first found field/function will be - used for conversion. This may lead to wrong results and probably should - be fixed. */ static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) { uint i; - Item::Type res= (Item::Type)0; - /* Used only for date/time fields, max_length = 19 */ - char buff[20]; - uchar null_byte; - Field *field= NULL; - - /* Search for date/time fields/functions */ - for (i= 0; i < nitems; i++) - { - if (!items[i]->result_as_longlong()) - { - /* Do not convert anything if a string field/function is present */ - if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT) - { - i= nitems; - break; - } - continue; - } - if ((res= items[i]->real_item()->type()) == Item::FIELD_ITEM && - items[i]->result_type() != INT_RESULT) - { - field= ((Item_field *)items[i]->real_item())->field; - break; - } - else if (res == Item::FUNC_ITEM) - { - field= items[i]->tmp_table_field_from_field_type(0); - if (field) - field->move_field(buff, &null_byte, 0); - break; - } - } - if (field) - { - /* Check the rest of the list for presence of a string field/function. */ - for (i++ ; i < nitems; i++) - { - if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT && - !items[i]->result_as_longlong()) - { - if (res == Item::FUNC_ITEM) - delete field; - field= 0; - break; - } - } - } - /* - If the first item is a date/time function then its result should be - compared as int - */ - if (field) - /* Suppose we are comparing dates */ - type[0]= INT_RESULT; - else - type[0]= items[0]->result_type(); - - for (i= 0; i < nitems ; i++) - { - Item_result result= items[i]->result_type(); - if (field && - ((!items[i]->const_item() && items[i]->result_as_longlong()) || - (items[i]->const_item() && convert_constant_item(thd, field, - &items[i])))) - result= INT_RESULT; - type[0]= item_cmp_type(type[0], result); - } - - if (res == Item::FUNC_ITEM && field) - delete field; + type[0]= items[0]->result_type(); + for (i= 1 ; i < nitems ; i++) + type[0]= item_cmp_type(type[0], items[i]->result_type()); } static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, @@ -1021,8 +916,30 @@ void Item_func_between::fix_length_and_dec() if (!args[0] || !args[1] || !args[2]) return; agg_cmp_type(thd, &cmp_type, args, 3); - if (cmp_type == STRING_RESULT) - agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV); + if (cmp_type == STRING_RESULT && + agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV)) + return; + + /* + Make a special case of compare with date/time and longlong fields. + They are compared as integers, so for const item this time-consuming + conversion can be done only once, not for every single comparison + */ + if (args[0]->type() == FIELD_ITEM) + { + Field *field=((Item_field*) args[0])->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/mysql_priv.h b/sql/mysql_priv.h index 9c5bcc2d53f..4a5658c5ccf 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -305,6 +305,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout); #define TL_OPTION_UPDATING 1 #define TL_OPTION_FORCE_INDEX 2 #define TL_OPTION_IGNORE_LEAVES 4 +#define TL_OPTION_ALIAS 8 /* Some portable defines */ diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 57903ffe7b9..85125a4521a 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2980,6 +2980,14 @@ int QUICK_SELECT::get_next() } } +void QUICK_SELECT::reset(void) +{ + next= 0; + it.rewind(); + range= 0; + if (file->inited == handler::NONE) + file->ha_index_init(index); +} /* Get next for geometrical indexes */ @@ -3201,7 +3209,11 @@ bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg, return 0; } #endif - +void QUICK_SELECT_DESC::reset(void) +{ + rev_it.rewind(); + QUICK_SELECT::reset(); +} /***************************************************************************** ** Print a quick range for debugging diff --git a/sql/opt_range.h b/sql/opt_range.h index d2f4452a762..367a85dc6f2 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -86,7 +86,7 @@ public: QUICK_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0); virtual ~QUICK_SELECT(); - void reset(void) { next=0; it.rewind(); range= NULL;} + virtual void reset(void); int init() { key_part_info= head->key_info[index].key_part; @@ -120,7 +120,7 @@ private: #ifdef NOT_USED bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts); #endif - void reset(void) { next=0; rev_it.rewind(); } + void reset(void); List rev_ranges; List_iterator rev_it; }; diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 64b01ce002a..412fc0dc037 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -187,7 +187,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) Type of range for the key part for this field will be returned in range_fl. */ - if ((outer_tables & table->map) || + if (table->file->inited || (outer_tables & table->map) || !find_key_for_maxmin(0, &ref, item_field->field, conds, &range_fl, &prefix_len)) { @@ -274,7 +274,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) Type of range for the key part for this field will be returned in range_fl. */ - if ((outer_tables & table->map) || + if (table->file->inited || (outer_tables & table->map) || !find_key_for_maxmin(1, &ref, item_field->field, conds, &range_fl, &prefix_len)) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 89ecceeb1bf..59c4026ba7f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4863,6 +4863,7 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc) table_options A set of the following bits: TL_OPTION_UPDATING Table will be updated TL_OPTION_FORCE_INDEX Force usage of index + TL_OPTION_ALIAS an alias in multi table DELETE lock_type How table should be locked use_index List of indexed used in USE INDEX ignore_index List of indexed used in IGNORE INDEX @@ -4888,7 +4889,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (!table) DBUG_RETURN(0); // End of memory alias_str= alias ? alias->str : table->table.str; - if (check_table_name(table->table.str,table->table.length) || + if (!test(table_options & TL_OPTION_ALIAS) && + check_table_name(table->table.str,table->table.length) || table->db.str && check_db_name(table->db.str)) { net_printf(thd, ER_WRONG_TABLE_NAME, table->table.str); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f02c3216d9a..36959ee1d0f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1133,7 +1133,7 @@ JOIN::exec() DBUG_VOID_RETURN; } - if (!tables_list) + if (!tables_list && (tables || !select_lex->with_sum_func)) { // Only test of functions if (select_options & SELECT_DESCRIBE) select_describe(this, FALSE, FALSE, FALSE, @@ -1172,7 +1172,12 @@ JOIN::exec() thd->examined_row_count= 0; DBUG_VOID_RETURN; } - thd->limit_found_rows= thd->examined_row_count= 0; + /* + don't reset the found rows count if there're no tables + as FOUND_ROWS() may be called. + */ + if (tables) + thd->limit_found_rows= thd->examined_row_count= 0; if (zero_result_cause) { @@ -1211,7 +1216,8 @@ JOIN::exec() having= tmp_having; select_describe(this, need_tmp, order != 0 && !skip_sort_order, - select_distinct); + select_distinct, + !tables ? "No tables used" : NullS); DBUG_VOID_RETURN; } @@ -6044,9 +6050,12 @@ 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; + if (join->tables) + { + join->join_tab[join->tables-1].next_select=end_select; - join_tab=join->join_tab+join->const_tables; + join_tab=join->join_tab+join->const_tables; + } join->send_records=0; if (join->tables == join->const_tables) { @@ -6064,6 +6073,7 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) } else { + DBUG_ASSERT(join_tab); error= sub_select(join,join_tab,0); if (error >= 0) error= sub_select(join,join_tab,1); @@ -9095,6 +9105,8 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, param->copy_funcs.empty(); for (i= 0; (pos= li++); i++) { + Field *field; + char *tmp; if (pos->type() == Item::FIELD_ITEM) { Item_field *item; @@ -9123,14 +9135,22 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, set up save buffer and change result_field to point at saved value */ - Field *field= item->field; + field= item->field; item->result_field=field->new_field(thd->mem_root,field->table); - char *tmp=(char*) sql_alloc(field->pack_length()+1); + /* + We need to allocate one extra byte for null handling and + another extra byte to not get warnings from purify in + Field_string::val_int + */ + tmp= (char*) sql_alloc(field->pack_length()+2); if (!tmp) goto err; copy->set(tmp, item->result_field); item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1); - copy++; +#ifdef HAVE_purify + copy->to_ptr[copy->from_length]= 0; +#endif + copy++; } } else if ((pos->type() == Item::FUNC_ITEM || diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index efd83549312..c6f4307f1ea 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4345,14 +4345,17 @@ table_wild_one: ident opt_wild opt_table_alias { if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3, - TL_OPTION_UPDATING, Lex->lock_option)) + TL_OPTION_UPDATING | + TL_OPTION_ALIAS, Lex->lock_option)) YYABORT; } | ident '.' ident opt_wild opt_table_alias { if (!Select->add_table_to_list(YYTHD, new Table_ident(YYTHD, $1, $3, 0), - $5, TL_OPTION_UPDATING, + $5, + TL_OPTION_UPDATING | + TL_OPTION_ALIAS, Lex->lock_option)) YYABORT; } @@ -4800,14 +4803,16 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING_sys LOAD TABLE_SYM table_ident FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE; + WARN_DEPRECATED("LOAD TABLE FROM MASTER", "mysqldump or future BACKUP/RESTORE DATABASE facility"); if (!Select->add_table_to_list(YYTHD, $3, NULL, TL_OPTION_UPDATING)) YYABORT; - + } | LOAD DATA_SYM FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_DATA; + WARN_DEPRECATED("LOAD DATA FROM MASTER", "mysqldump or future BACKUP/RESTORE DATABASE facility"); }; opt_local: