Commit 3bd89574 authored by andrey@lmy004's avatar andrey@lmy004

Merge ahristov@bk-internal.mysql.com:/home/bk/mysql-5.1-new

into lmy004.:/work/mysql-5.1-bug17289
parents a01ed154 4b18b5e7
...@@ -194,7 +194,7 @@ static int com_quit(String *str,char*), ...@@ -194,7 +194,7 @@ static int com_quit(String *str,char*),
com_connect(String *str,char*), com_status(String *str,char*), com_connect(String *str,char*), com_status(String *str,char*),
com_use(String *str,char*), com_source(String *str, char*), com_use(String *str,char*), com_source(String *str, char*),
com_rehash(String *str, char*), com_tee(String *str, char*), com_rehash(String *str, char*), com_tee(String *str, char*),
com_notee(String *str, char*), com_notee(String *str, char*), com_charset(String *str,char*),
com_prompt(String *str, char*), com_delimiter(String *str, char*), com_prompt(String *str, char*), com_delimiter(String *str, char*),
com_warnings(String *str, char*), com_nowarnings(String *str, char*); com_warnings(String *str, char*), com_nowarnings(String *str, char*);
...@@ -268,6 +268,8 @@ static COMMANDS commands[] = { ...@@ -268,6 +268,8 @@ static COMMANDS commands[] = {
"Set outfile [to_outfile]. Append everything into given outfile." }, "Set outfile [to_outfile]. Append everything into given outfile." },
{ "use", 'u', com_use, 1, { "use", 'u', com_use, 1,
"Use another database. Takes database name as argument." }, "Use another database. Takes database name as argument." },
{ "charset", 'C', com_charset, 1,
"Switch to another charset. Might be needed for processing binlog with multi-byte charsets." },
{ "warnings", 'W', com_warnings, 0, { "warnings", 'W', com_warnings, 0,
"Show warnings after every statement." }, "Show warnings after every statement." },
{ "nowarning", 'w', com_nowarnings, 0, { "nowarning", 'w', com_nowarnings, 0,
...@@ -1909,6 +1911,28 @@ com_clear(String *buffer,char *line __attribute__((unused))) ...@@ -1909,6 +1911,28 @@ com_clear(String *buffer,char *line __attribute__((unused)))
return 0; return 0;
} }
/* ARGSUSED */
static int
com_charset(String *buffer __attribute__((unused)), char *line)
{
char buff[256], *param;
CHARSET_INFO * new_cs;
strmake(buff, line, sizeof(buff) - 1);
param= get_arg(buff, 0);
if (!param || !*param)
{
return put_info("Usage: \\C char_setname | charset charset_name",
INFO_ERROR, 0);
}
new_cs= get_charset_by_csname(param, MY_CS_PRIMARY, MYF(MY_WME));
if (new_cs)
{
charset_info= new_cs;
put_info("Charset changed", INFO_INFO);
}
else put_info("Charset is not found", INFO_INFO);
return 0;
}
/* /*
Execute command Execute command
......
...@@ -15,6 +15,7 @@ use test; ...@@ -15,6 +15,7 @@ use test;
SET TIMESTAMP=10000; SET TIMESTAMP=10000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t2 values (@v); insert into t2 values (@v);
# End of log file # End of log file
......
...@@ -121,3 +121,10 @@ a NULLIF(a,'') ...@@ -121,3 +121,10 @@ a NULLIF(a,'')
NULL NULL NULL NULL
NULL NULL
DROP TABLE t1; DROP TABLE t1;
create table t1 (f1 int, f2 int);
insert into t1 values(1,1),(0,0);
select f1, f2, if(f1, 40.0, 5.00) from t1 group by f1 order by f2;
f1 f2 if(f1, 40.0, 5.00)
0 0 5.00
1 1 40.00
drop table t1;
...@@ -59,3 +59,13 @@ database() ...@@ -59,3 +59,13 @@ database()
test test
unlock tables; unlock tables;
drop table t1; drop table t1;
c_cp932
...@@ -20,6 +20,7 @@ use test; ...@@ -20,6 +20,7 @@ use test;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
drop table if exists t1,t2; drop table if exists t1,t2;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
...@@ -50,6 +51,7 @@ use test; ...@@ -50,6 +51,7 @@ use test;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values ("Alas"); insert into t1 values ("Alas");
# End of log file # End of log file
...@@ -72,6 +74,7 @@ use test; ...@@ -72,6 +74,7 @@ use test;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values ("Alas"); insert into t1 values ("Alas");
# End of log file # End of log file
...@@ -86,6 +89,7 @@ use test; ...@@ -86,6 +89,7 @@ use test;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
drop table if exists t1,t2; drop table if exists t1,t2;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
...@@ -116,6 +120,7 @@ use test; ...@@ -116,6 +120,7 @@ use test;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values ("Alas"); insert into t1 values ("Alas");
# End of log file # End of log file
...@@ -138,6 +143,7 @@ use test; ...@@ -138,6 +143,7 @@ use test;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
insert into t1 values ("Alas"); insert into t1 values ("Alas");
# End of log file # End of log file
...@@ -166,4 +172,21 @@ insert t1 values (1); ...@@ -166,4 +172,21 @@ insert t1 values (1);
# End of log file # End of log file
ROLLBACK /* added by mysqlbinlog */; ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
drop table t1, t2; flush logs;
create table t3 (f text character set utf8);
create table t4 (f text character set cp932);
flush logs;
rename table t3 to t03, t4 to t04;
select HEX(f) from t03;
HEX(f)
E382BD
select HEX(f) from t3;
HEX(f)
E382BD
select HEX(f) from t04;
HEX(f)
835C
select HEX(f) from t4;
HEX(f)
835C
drop table t1, t2, t03, t04, t3, t4;
This diff is collapsed.
...@@ -2666,8 +2666,6 @@ We the people in order to perform ...@@ -2666,8 +2666,6 @@ We the people in order to perform
a more perfect union a more perfect union
test.t1: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0 test.t1: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
test.t2: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0 test.t2: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
test.t1: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
test.t2: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
select * from t1; select * from t1;
a b a b
Duck, Duck goose Duck, Duck goose
......
...@@ -278,3 +278,25 @@ partition p1 values in (14) ...@@ -278,3 +278,25 @@ partition p1 values in (14)
insert into t1 values (10,1); insert into t1 values (10,1);
ERROR HY000: Table has no partition for value 11 ERROR HY000: Table has no partition for value 11
drop table t1; drop table t1;
create table t1 (f1 integer,f2 integer, f3 varchar(10), primary key(f1,f2))
partition by range(f1) subpartition by hash(f2) subpartitions 2
(partition p1 values less than (0),
partition p2 values less than (2),
partition p3 values less than (2147483647));
insert into t1 values(10,10,'10');
insert into t1 values(2,2,'2');
select * from t1 where f1 = 2;
f1 f2 f3
2 2 2
drop table t1;
create table t1 (f1 integer,f2 integer, unique index(f1))
partition by range(f1 div 2)
subpartition by hash(f1) subpartitions 2
(partition partb values less than (2),
partition parte values less than (4),
partition partf values less than (10000));
insert into t1 values(10,1);
select * from t1 where f1 = 10;
f1 f2
10 1
drop table t1;
...@@ -180,6 +180,7 @@ ROLLBACK; ...@@ -180,6 +180,7 @@ ROLLBACK;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
drop database if exists mysqltest2; drop database if exists mysqltest2;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
...@@ -187,9 +188,11 @@ drop database if exists mysqltest3; ...@@ -187,9 +188,11 @@ drop database if exists mysqltest3;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
create database mysqltest2 character set latin2; create database mysqltest2 character set latin2;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=30; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=30;
create database mysqltest3; create database mysqltest3;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=64; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=64;
drop database mysqltest3; drop database mysqltest3;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
...@@ -199,6 +202,7 @@ SET TIMESTAMP=1000000000; ...@@ -199,6 +202,7 @@ SET TIMESTAMP=1000000000;
create table t1 (a int auto_increment primary key, b varchar(100)); create table t1 (a int auto_increment primary key, b varchar(100));
SET INSERT_ID=1; SET INSERT_ID=1;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
/*!\C cp850 */;
SET @@session.character_set_client=4,@@session.collation_connection=27,@@session.collation_server=64; SET @@session.character_set_client=4,@@session.collation_connection=27,@@session.collation_server=64;
insert into t1 (b) values(@@character_set_server); insert into t1 (b) values(@@character_set_server);
SET INSERT_ID=2; SET INSERT_ID=2;
...@@ -214,6 +218,7 @@ SET INSERT_ID=5; ...@@ -214,6 +218,7 @@ SET INSERT_ID=5;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
insert into t1 (b) values(@@collation_connection); insert into t1 (b) values(@@collation_connection);
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=5,@@session.collation_server=64; SET @@session.character_set_client=8,@@session.collation_connection=5,@@session.collation_server=64;
truncate table t1; truncate table t1;
SET INSERT_ID=1; SET INSERT_ID=1;
...@@ -224,6 +229,7 @@ SET TIMESTAMP=1000000000; ...@@ -224,6 +229,7 @@ SET TIMESTAMP=1000000000;
insert into t1 (b) values(LEAST("Mller","Muffler")); insert into t1 (b) values(LEAST("Mller","Muffler"));
SET INSERT_ID=3; SET INSERT_ID=3;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=31,@@session.collation_server=64; SET @@session.character_set_client=8,@@session.collation_connection=31,@@session.collation_server=64;
insert into t1 (b) values(@@collation_connection); insert into t1 (b) values(@@collation_connection);
SET INSERT_ID=4; SET INSERT_ID=4;
...@@ -241,9 +247,11 @@ SET TIMESTAMP=1000000000; ...@@ -241,9 +247,11 @@ SET TIMESTAMP=1000000000;
drop database mysqltest3; drop database mysqltest3;
use test; use test;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=30; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=30;
CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255)); CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255));
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
/*!\C koi8r */;
SET @@session.character_set_client=7,@@session.collation_connection=51,@@session.collation_server=30; SET @@session.character_set_client=7,@@session.collation_connection=51,@@session.collation_server=30;
INSERT INTO t1 (c1, c2) VALUES (', ',', '); INSERT INTO t1 (c1, c2) VALUES (', ',', ');
# End of log file # End of log file
......
This diff is collapsed.
...@@ -155,11 +155,11 @@ Pos Instruction ...@@ -155,11 +155,11 @@ Pos Instruction
0 stmt 9 "drop temporary table if exists sudoku..." 0 stmt 9 "drop temporary table if exists sudoku..."
1 stmt 1 "create temporary table sudoku_work ( ..." 1 stmt 1 "create temporary table sudoku_work ( ..."
2 stmt 1 "create temporary table sudoku_schedul..." 2 stmt 1 "create temporary table sudoku_schedul..."
3 stmt 94 "call sudoku_init(" 3 stmt 95 "call sudoku_init("
4 jump_if_not 7(8) p_naive@0 4 jump_if_not 7(8) p_naive@0
5 stmt 4 "update sudoku_work set cnt = 0 where ..." 5 stmt 4 "update sudoku_work set cnt = 0 where ..."
6 jump 8 6 jump 8
7 stmt 94 "call sudoku_count(" 7 stmt 95 "call sudoku_count("
8 stmt 6 "insert into sudoku_schedule (row,col)..." 8 stmt 6 "insert into sudoku_schedule (row,col)..."
9 set v_scounter@2 0 9 set v_scounter@2 0
10 set v_i@3 1 10 set v_i@3 1
......
...@@ -21,6 +21,7 @@ use test; ...@@ -21,6 +21,7 @@ use test;
SET TIMESTAMP=10000; SET TIMESTAMP=10000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0; SET @@session.sql_mode=0;
/*!\C latin1 */;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
INSERT INTO t1 VALUES(@`a b`); INSERT INTO t1 VALUES(@`a b`);
SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`; SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`;
......
...@@ -33,10 +33,8 @@ rpl_until : Unstable test case, bug#15886 ...@@ -33,10 +33,8 @@ rpl_until : Unstable test case, bug#15886
sp-goto : GOTO is currently is disabled - will be fixed in the future sp-goto : GOTO is currently is disabled - will be fixed in the future
subselect : Bug#15706 (ps mode) [PATCH PENDING] subselect : Bug#15706 (ps mode) [PATCH PENDING]
rpl_ndb_log : result not deterministic rpl_ndb_log : result not deterministic
sp-code : Bug #17360
binlog_row_mix_innodb_myisam : Bug #17386 binlog_row_mix_innodb_myisam : Bug #17386
binlog_row_insert_select : Bug #17385 binlog_row_insert_select : Bug #17385
rpl_row_basic_2myisam : Bug #17385 rpl_row_basic_2myisam : Bug #17385
rpl_row_basic_3innodb : Bug #17385 rpl_row_basic_3innodb : Bug #17385
rpl_row_create_table : Bug #17385 rpl_row_create_table : Bug #17385
mysqldump : Bug #17383 Bug #17384
...@@ -89,3 +89,11 @@ SELECT a, NULLIF(a,'') FROM t1 WHERE NULLIF(a,'') IS NULL; ...@@ -89,3 +89,11 @@ SELECT a, NULLIF(a,'') FROM t1 WHERE NULLIF(a,'') IS NULL;
DROP TABLE t1; DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
#
# Bug #16272 IF function with decimal args can produce wrong result
#
create table t1 (f1 int, f2 int);
insert into t1 values(1,1),(0,0);
select f1, f2, if(f1, 40.0, 5.00) from t1 group by f1 order by f2;
drop table t1;
...@@ -43,3 +43,16 @@ lock tables t1 write; ...@@ -43,3 +43,16 @@ lock tables t1 write;
unlock tables; unlock tables;
drop table t1; drop table t1;
#
# BUG#16217 - MySQL client misinterpretes multi-byte char as escape `\'
#
# new command \C or charset
--exec $MYSQL --default-character-set=utf8 test -e "\C cp932 \g"
--exec $MYSQL --default-character-set=cp932 test -e "charset utf8;"
# its usage to switch internally in mysql to requested charset
--exec $MYSQL --default-character-set=utf8 test -e "charset cp932; set @@session.character_set_client= cp932; select '\'; create table t1 (c_cp932 TEXT CHARACTER SET cp932); insert into t1 values('\'); select * from t1; drop table t1;"
--exec $MYSQL --default-character-set=utf8 test -e "charset cp932; set character_set_client= cp932; select '\'"
--exec $MYSQL --default-character-set=utf8 test -e "/*charset cp932 */; set character_set_client= cp932; select '\'"
--exec $MYSQL --default-character-set=utf8 test -e "/*!\C cp932 */; set character_set_client= cp932; select '\'"
...@@ -109,7 +109,24 @@ select "--- reading stdin --" as ""; ...@@ -109,7 +109,24 @@ select "--- reading stdin --" as "";
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form --position=79 - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001 --exec $MYSQL_BINLOG --short-form --position=79 - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001
# Bug#16217 (mysql client did not know how not switch its internal charset)
flush logs;
create table t3 (f text character set utf8);
create table t4 (f text character set cp932);
--exec $MYSQL --default-character-set=utf8 test -e "insert into t3 values(_utf8'ソ')"
--exec $MYSQL --default-character-set=cp932 test -e "insert into t4 values(_cp932'\');"
flush logs;
rename table t3 to t03, t4 to t04;
--exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000004 | $MYSQL --default-character-set=utf8
# original and recovered data must be equal
select HEX(f) from t03;
select HEX(f) from t3;
select HEX(f) from t04;
select HEX(f) from t4;
# clean up # clean up
drop table t1, t2; drop table t1, t2, t03, t04, t3, t4;
# End of 4.1 tests # End of 4.1 tests
...@@ -1066,7 +1066,7 @@ select * from t2; ...@@ -1066,7 +1066,7 @@ select * from t2;
# The first load tests the pausing code # The first load tests the pausing code
--exec $MYSQL_IMPORT --use-threads=1 test $MYSQLTEST_VARDIR/tmp/t1.txt $MYSQLTEST_VARDIR/tmp/t2.txt --exec $MYSQL_IMPORT --use-threads=1 test $MYSQLTEST_VARDIR/tmp/t1.txt $MYSQLTEST_VARDIR/tmp/t2.txt
# Now we test with multiple threads! # Now we test with multiple threads!
--exec $MYSQL_IMPORT --use-threads=5 test $MYSQLTEST_VARDIR/tmp/t1.txt $MYSQLTEST_VARDIR/tmp/t2.txt --exec $MYSQL_IMPORT --silent --use-threads=5 test $MYSQLTEST_VARDIR/tmp/t1.txt $MYSQLTEST_VARDIR/tmp/t2.txt
select * from t1; select * from t1;
select * from t2; select * from t2;
......
...@@ -353,3 +353,30 @@ insert into t1 values (10,1); ...@@ -353,3 +353,30 @@ insert into t1 values (10,1);
drop table t1; drop table t1;
#
# Bug#16901 Partitions: crash, SELECT, column of part.
# function=first column of primary key
#
create table t1 (f1 integer,f2 integer, f3 varchar(10), primary key(f1,f2))
partition by range(f1) subpartition by hash(f2) subpartitions 2
(partition p1 values less than (0),
partition p2 values less than (2),
partition p3 values less than (2147483647));
insert into t1 values(10,10,'10');
insert into t1 values(2,2,'2');
select * from t1 where f1 = 2;
drop table t1;
#
# Bug #16907 Partitions: crash, SELECT goes into last partition, UNIQUE INDEX
#
create table t1 (f1 integer,f2 integer, unique index(f1))
partition by range(f1 div 2)
subpartition by hash(f1) subpartitions 2
(partition partb values less than (2),
partition parte values less than (4),
partition partf values less than (10000));
insert into t1 values(10,1);
select * from t1 where f1 = 10;
drop table t1;
...@@ -164,7 +164,103 @@ drop table t1,t2; ...@@ -164,7 +164,103 @@ drop table t1,t2;
drop database other; drop database other;
# #
# End of test # Test specific triggers including SELECT into var with replication
# BUG#13227:
# slave performs an update to the replicatable table, t1,
# and modifies its local data, t3, by mean of its local trigger that uses
# another local table t2.
# Expected values are commented into queries.
#
# Body of the test executes in a loop since the problem occurred randomly.
#
let $max_rows=5;
let $rnd=10;
--echo test case for BUG#13227
while ($rnd)
{
--echo -------------------
echo $rnd;
--echo -------------------
### SETUP
--disable_warnings
connection master;
eval drop table if exists t1$rnd;
connection slave;
eval drop table if exists t2$rnd,t3$rnd;
--enable_warnings
connection master;
eval create table t1$rnd (f1 int) /* 2 replicate */;
let $i=$max_rows;
while ($i)
{
eval insert into t1$rnd values (-$i);
dec $i;
}
sync_slave_with_master;
#connection slave;
eval select * from t1$rnd;
delimiter |;
eval create trigger trg1$rnd before update on t1$rnd /* slave local */
for each row
begin
DECLARE r integer;
SELECT f2 INTO r FROM t2$rnd where f1=NEW.f1;
INSERT INTO t3$rnd values (r);
end|
delimiter ;|
eval create table t2$rnd (f1 int, f2 int) /* slave local */;
eval create table t3$rnd (f3 int) /* slave local */;
let $i=$max_rows;
while ($i)
{
eval insert into t2$rnd values ($i, $i*100);
dec $i;
}
### Test
#connection slave;
# trigger works as specified when updates from slave
eval select * from t2$rnd;
eval UPDATE t1$rnd SET f1=$max_rows where f1=-$max_rows;
eval SELECT * from t1$rnd /* must be f1 $max_rows, 1 - $max_rows 2 - $max_rows ... -1 */;
eval SELECT * from t3$rnd /* must be f3 $max_rows*100 */;
connection master;
let $i=$max_rows;
while ($i)
{
eval UPDATE t1$rnd SET f1=$i where f1=-$i;
dec $i;
}
sync_slave_with_master;
#connection slave;
eval SELECT * from t1$rnd /* must be f1 $max_rows ... 1 */;
eval SELECT * from t3$rnd /* must be f3 $max_rows * 100 ... 100 */;
### CLEANUP
#connection slave;
eval drop trigger trg1$rnd;
eval drop table t2$rnd,t3$rnd;
connection master;
eval drop table t1$rnd;
dec $rnd;
}
#
# End of tests
# #
save_master_pos; save_master_pos;
connection slave; connection slave;
......
...@@ -2198,6 +2198,7 @@ int ha_ndbcluster::full_table_scan(byte *buf) ...@@ -2198,6 +2198,7 @@ int ha_ndbcluster::full_table_scan(byte *buf)
int res; int res;
NdbScanOperation *op; NdbScanOperation *op;
NdbTransaction *trans= m_active_trans; NdbTransaction *trans= m_active_trans;
part_id_range part_spec;
DBUG_ENTER("full_table_scan"); DBUG_ENTER("full_table_scan");
DBUG_PRINT("enter", ("Starting new scan on %s", m_tabname)); DBUG_PRINT("enter", ("Starting new scan on %s", m_tabname));
...@@ -2209,6 +2210,35 @@ int ha_ndbcluster::full_table_scan(byte *buf) ...@@ -2209,6 +2210,35 @@ int ha_ndbcluster::full_table_scan(byte *buf)
op->readTuples(lm, 0, parallelism)) op->readTuples(lm, 0, parallelism))
ERR_RETURN(trans->getNdbError()); ERR_RETURN(trans->getNdbError());
m_active_cursor= op; m_active_cursor= op;
if (m_use_partition_function)
{
part_spec.start_part= 0;
part_spec.end_part= get_tot_partitions(m_part_info) - 1;
prune_partition_set(table, &part_spec);
DBUG_PRINT("info", ("part_spec.start_part = %u, part_spec.end_part = %u",
part_spec.start_part, part_spec.end_part));
/*
If partition pruning has found no partition in set
we can return HA_ERR_END_OF_FILE
If partition pruning has found exactly one partition in set
we can optimize scan to run towards that partition only.
*/
if (part_spec.start_part > part_spec.end_part)
{
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
else if (part_spec.start_part == part_spec.end_part)
{
/*
Only one partition is required to scan, if sorted is required we
don't need it any more since output from one ordered partitioned
index is always sorted.
*/
m_active_cursor->setPartitionId(part_spec.start_part);
}
}
if (generate_scan_filter(m_cond_stack, op)) if (generate_scan_filter(m_cond_stack, op))
DBUG_RETURN(ndb_err(trans)); DBUG_RETURN(ndb_err(trans));
if ((res= define_read_attrs(buf, op))) if ((res= define_read_attrs(buf, op)))
...@@ -3012,6 +3042,14 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, ...@@ -3012,6 +3042,14 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key,
if (m_use_partition_function) if (m_use_partition_function)
{ {
get_partition_set(table, buf, active_index, start_key, &part_spec); get_partition_set(table, buf, active_index, start_key, &part_spec);
DBUG_PRINT("info", ("part_spec.start_part = %u, part_spec.end_part = %u",
part_spec.start_part, part_spec.end_part));
/*
If partition pruning has found no partition in set
we can return HA_ERR_END_OF_FILE
If partition pruning has found exactly one partition in set
we can optimize scan to run towards that partition only.
*/
if (part_spec.start_part > part_spec.end_part) if (part_spec.start_part > part_spec.end_part)
{ {
DBUG_RETURN(HA_ERR_END_OF_FILE); DBUG_RETURN(HA_ERR_END_OF_FILE);
...@@ -3026,6 +3064,7 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, ...@@ -3026,6 +3064,7 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key,
sorted= FALSE; sorted= FALSE;
} }
} }
m_write_op= FALSE; m_write_op= FALSE;
switch (type){ switch (type){
case PRIMARY_KEY_ORDERED_INDEX: case PRIMARY_KEY_ORDERED_INDEX:
...@@ -7003,6 +7042,12 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, ...@@ -7003,6 +7042,12 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
get_partition_set(table, curr, active_index, get_partition_set(table, curr, active_index,
&multi_range_curr->start_key, &multi_range_curr->start_key,
&part_spec); &part_spec);
DBUG_PRINT("info", ("part_spec.start_part = %u, part_spec.end_part = %u",
part_spec.start_part, part_spec.end_part));
/*
If partition pruning has found no partition in set
we can skip this scan
*/
if (part_spec.start_part > part_spec.end_part) if (part_spec.start_part > part_spec.end_part)
{ {
/* /*
......
...@@ -1126,6 +1126,7 @@ char *generate_partition_syntax(partition_info *part_info, ...@@ -1126,6 +1126,7 @@ char *generate_partition_syntax(partition_info *part_info,
uint *buf_length, bool use_sql_alloc, uint *buf_length, bool use_sql_alloc,
bool write_all); bool write_all);
bool partition_key_modified(TABLE *table, List<Item> &fields); bool partition_key_modified(TABLE *table, List<Item> &fields);
void prune_partition_set(const TABLE *table, part_id_range *part_spec);
void get_partition_set(const TABLE *table, byte *buf, const uint index, void get_partition_set(const TABLE *table, byte *buf, const uint index,
const key_range *key_spec, const key_range *key_spec,
part_id_range *part_spec); part_id_range *part_spec);
......
...@@ -1383,7 +1383,8 @@ Item_func_if::fix_length_and_dec() ...@@ -1383,7 +1383,8 @@ Item_func_if::fix_length_and_dec()
max_length= max_length=
(cached_result_type == DECIMAL_RESULT || cached_result_type == INT_RESULT) ? (cached_result_type == DECIMAL_RESULT || cached_result_type == INT_RESULT) ?
(max(args[1]->max_length - args[1]->decimals, (max(args[1]->max_length - args[1]->decimals,
args[2]->max_length - args[2]->decimals) + decimals) : args[2]->max_length - args[2]->decimals) + decimals +
(unsigned_flag ? 0 : 1) ) :
max(args[1]->max_length, args[2]->max_length); max(args[1]->max_length, args[2]->max_length);
} }
......
...@@ -1610,6 +1610,11 @@ void Query_log_event::print_query_header(FILE* file, ...@@ -1610,6 +1610,11 @@ void Query_log_event::print_query_header(FILE* file,
} }
if (unlikely(bcmp(print_event_info->charset, charset, 6))) if (unlikely(bcmp(print_event_info->charset, charset, 6)))
{ {
CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
if (cs_info)
{
fprintf(file, "/*!\\C %s */;\n", cs_info->csname); /* for mysql client */
}
fprintf(file,"SET " fprintf(file,"SET "
"@@session.character_set_client=%d," "@@session.character_set_client=%d,"
"@@session.collation_connection=%d," "@@session.collation_connection=%d,"
......
...@@ -3605,7 +3605,52 @@ void get_full_part_id_from_key(const TABLE *table, byte *buf, ...@@ -3605,7 +3605,52 @@ void get_full_part_id_from_key(const TABLE *table, byte *buf,
part_spec->start_part++; part_spec->start_part++;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/*
Prune the set of partitions to use in query
SYNOPSIS
prune_partition_set()
table The table object
out:part_spec Contains start part, end part
DESCRIPTION
This function is called to prune the range of partitions to scan by
checking the used_partitions bitmap.
If start_part > end_part at return it means no partition needs to be
scanned. If start_part == end_part it always means a single partition
needs to be scanned.
RETURN VALUE
part_spec
*/
void prune_partition_set(const TABLE *table, part_id_range *part_spec)
{
int last_partition= -1;
uint i;
partition_info *part_info= table->part_info;
DBUG_ENTER("prune_partition_set");
for (i= part_spec->start_part; i <= part_spec->end_part; i++)
{
if (bitmap_is_set(&(part_info->used_partitions), i))
{
DBUG_PRINT("info", ("Partition %d is set", i));
if (last_partition == -1)
/* First partition found in set and pruned bitmap */
part_spec->start_part= i;
last_partition= i;
}
}
if (last_partition == -1)
/* No partition found in pruned bitmap */
part_spec->start_part= part_spec->end_part + 1;
else //if (last_partition != -1)
part_spec->end_part= last_partition;
DBUG_VOID_RETURN;
}
/* /*
Get the set of partitions to use in query. Get the set of partitions to use in query.
...@@ -3669,6 +3714,10 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index, ...@@ -3669,6 +3714,10 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index,
is needed. is needed.
*/ */
get_full_part_id_from_key(table,buf,key_info,key_spec,part_spec); get_full_part_id_from_key(table,buf,key_info,key_spec,part_spec);
/*
Check if range can be adjusted by looking in used_partitions
*/
prune_partition_set(table, part_spec);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
else if (is_sub_partitioned(part_info)) else if (is_sub_partitioned(part_info))
...@@ -3711,6 +3760,10 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index, ...@@ -3711,6 +3760,10 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index,
*/ */
get_full_part_id_from_key(table,buf,key_info,key_spec,part_spec); get_full_part_id_from_key(table,buf,key_info,key_spec,part_spec);
clear_indicator_in_key_fields(key_info); clear_indicator_in_key_fields(key_info);
/*
Check if range can be adjusted by looking in used_partitions
*/
prune_partition_set(table, part_spec);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
else if (is_sub_partitioned(part_info)) else if (is_sub_partitioned(part_info))
...@@ -3754,7 +3807,7 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index, ...@@ -3754,7 +3807,7 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index,
subpartitions. This is a range without holes. subpartitions. This is a range without holes.
*/ */
DBUG_ASSERT(sub_part == no_parts); DBUG_ASSERT(sub_part == no_parts);
part_spec->start_part= part_part * part_info->no_parts; part_spec->start_part= part_part * part_info->no_subparts;
part_spec->end_part= part_spec->start_part+part_info->no_subparts - 1; part_spec->end_part= part_spec->start_part+part_info->no_subparts - 1;
} }
else else
...@@ -3770,10 +3823,13 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index, ...@@ -3770,10 +3823,13 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index,
} }
if (found_part_field) if (found_part_field)
clear_indicator_in_key_fields(key_info); clear_indicator_in_key_fields(key_info);
/*
Check if range can be adjusted by looking in used_partitions
*/
prune_partition_set(table, part_spec);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /*
If the table is partitioned we will read the partition info into the If the table is partitioned we will read the partition info into the
.frm file here. .frm file here.
...@@ -6009,7 +6065,10 @@ static uint32 get_next_partition_via_walking(PARTITION_ITERATOR *part_iter) ...@@ -6009,7 +6065,10 @@ static uint32 get_next_partition_via_walking(PARTITION_ITERATOR *part_iter)
field->store(part_iter->field_vals.start, FALSE); field->store(part_iter->field_vals.start, FALSE);
part_iter->field_vals.start++; part_iter->field_vals.start++;
longlong dummy; longlong dummy;
if (!part_iter->part_info->get_partition_id(part_iter->part_info, if (is_sub_partitioned(part_iter->part_info) &&
!part_iter->part_info->get_part_partition_id(part_iter->part_info,
&part_id, &dummy) ||
!part_iter->part_info->get_partition_id(part_iter->part_info,
&part_id, &dummy)) &part_id, &dummy))
return part_id; return part_id;
} }
......
...@@ -12823,11 +12823,12 @@ calc_group_buffer(JOIN *join,ORDER *group) ...@@ -12823,11 +12823,12 @@ calc_group_buffer(JOIN *join,ORDER *group)
Field *field= group_item->get_tmp_table_field(); Field *field= group_item->get_tmp_table_field();
if (field) if (field)
{ {
if (field->type() == FIELD_TYPE_BLOB) enum_field_types type;
if ((type= field->type()) == FIELD_TYPE_BLOB)
key_length+=MAX_BLOB_WIDTH; // Can't be used as a key key_length+=MAX_BLOB_WIDTH; // Can't be used as a key
else if (field->type() == MYSQL_TYPE_VARCHAR) else if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_VAR_STRING)
key_length+= field->field_length + HA_KEY_BLOB_LENGTH; key_length+= field->field_length + HA_KEY_BLOB_LENGTH;
else if (field->type() == FIELD_TYPE_BIT) else if (type == FIELD_TYPE_BIT)
{ {
/* Bit is usually stored as a longlong key for group fields */ /* Bit is usually stored as a longlong key for group fields */
key_length+= 8; // Big enough key_length+= 8; // Big enough
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment