mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 18:20:07 +01:00
Manual merge of mysql-5.1-bugteam into mysql-trunk-merge.
Conflicts: mysql-test/collections/default.experimental
This commit is contained in:
commit
3ba6a2a9fa
24 changed files with 424 additions and 75 deletions
|
@ -4192,7 +4192,7 @@ char *get_arg(char *line, my_bool get_next_arg)
|
||||||
if (*ptr == '\\' && ptr[1]) // escaped character
|
if (*ptr == '\\' && ptr[1]) // escaped character
|
||||||
{
|
{
|
||||||
// Remove the backslash
|
// Remove the backslash
|
||||||
strmov(ptr, ptr+1);
|
strmov_overlapp(ptr, ptr+1);
|
||||||
}
|
}
|
||||||
else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
|
else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,9 +95,7 @@ extern char NEAR _dig_vec_lower[];
|
||||||
/* Defined in strtod.c */
|
/* Defined in strtod.c */
|
||||||
extern const double log_10[309];
|
extern const double log_10[309];
|
||||||
|
|
||||||
#ifdef BAD_STRING_COMPILER
|
#ifndef strmov
|
||||||
#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
|
|
||||||
#else
|
|
||||||
#define strmov_overlapp(A,B) strmov(A,B)
|
#define strmov_overlapp(A,B) strmov(A,B)
|
||||||
#define strmake_overlapp(A,B,C) strmake(A,B,C)
|
#define strmake_overlapp(A,B,C) strmake(A,B,C)
|
||||||
#endif
|
#endif
|
||||||
|
@ -155,12 +153,11 @@ extern size_t strinstr(const char *str,const char *search);
|
||||||
extern size_t r_strinstr(const char *str, size_t from, const char *search);
|
extern size_t r_strinstr(const char *str, size_t from, const char *search);
|
||||||
extern char *strkey(char *dst,char *head,char *tail,char *flags);
|
extern char *strkey(char *dst,char *head,char *tail,char *flags);
|
||||||
extern char *strmake(char *dst,const char *src,size_t length);
|
extern char *strmake(char *dst,const char *src,size_t length);
|
||||||
#ifndef strmake_overlapp
|
|
||||||
extern char *strmake_overlapp(char *dst,const char *src, size_t length);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef strmov
|
#ifndef strmov
|
||||||
extern char *strmov(char *dst,const char *src);
|
extern char *strmov(char *dst,const char *src);
|
||||||
|
#else
|
||||||
|
extern char *strmov_overlapp(char *dst,const char *src);
|
||||||
#endif
|
#endif
|
||||||
extern char *strnmov(char *dst,const char *src,size_t n);
|
extern char *strnmov(char *dst,const char *src,size_t n);
|
||||||
extern char *strsuff(const char *src,const char *suffix);
|
extern char *strsuff(const char *src,const char *suffix);
|
||||||
|
|
|
@ -1338,6 +1338,13 @@ ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL;
|
||||||
affected rows: 0
|
affected rows: 0
|
||||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux)
|
||||||
|
# or freezes (win) the server
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a TEXT, id INT, b INT);
|
||||||
|
ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST;
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
CREATE TABLE t1(c CHAR(10),
|
CREATE TABLE t1(c CHAR(10),
|
||||||
i INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY);
|
i INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY);
|
||||||
|
|
|
@ -40,6 +40,26 @@ select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join
|
||||||
isbn city libname a
|
isbn city libname a
|
||||||
007 Berkeley Berkeley Public1 2
|
007 Berkeley Berkeley Public1 2
|
||||||
000 New York New York Public Libra 2
|
000 New York New York Public Libra 2
|
||||||
|
select t2.isbn,city,@bar:=t1.libname,count(distinct t1.libname) as a
|
||||||
|
from t3 left join t1 on t3.libname=t1.libname left join t2
|
||||||
|
on t3.isbn=t2.isbn group by city having count(distinct
|
||||||
|
t1.libname) > 1;
|
||||||
|
isbn city @bar:=t1.libname a
|
||||||
|
007 Berkeley Berkeley Public1 2
|
||||||
|
000 New York New York Public Libra 2
|
||||||
|
SELECT @bar;
|
||||||
|
@bar
|
||||||
|
Berkeley Public2
|
||||||
|
select t2.isbn,city,concat(@bar:=t1.libname),count(distinct t1.libname) as a
|
||||||
|
from t3 left join t1 on t3.libname=t1.libname left join t2
|
||||||
|
on t3.isbn=t2.isbn group by city having count(distinct
|
||||||
|
t1.libname) > 1;
|
||||||
|
isbn city concat(@bar:=t1.libname) a
|
||||||
|
007 Berkeley Berkeley Public1 2
|
||||||
|
000 New York New York Public Libra 2
|
||||||
|
SELECT @bar;
|
||||||
|
@bar
|
||||||
|
Berkeley Public2
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
create table t1 (f1 int);
|
create table t1 (f1 int);
|
||||||
insert into t1 values (1);
|
insert into t1 values (1);
|
||||||
|
|
|
@ -126,7 +126,7 @@ group by
|
||||||
a.text, b.id, b.betreff
|
a.text, b.id, b.betreff
|
||||||
order by
|
order by
|
||||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||||
ERROR 42S22: Unknown column 'b.betreff' in 'order clause'
|
ERROR 42000: Incorrect usage/placement of 'MATCH()'
|
||||||
select a.text, b.id, b.betreff
|
select a.text, b.id, b.betreff
|
||||||
from
|
from
|
||||||
t2 a inner join t3 b on a.id = b.forum inner join
|
t2 a inner join t3 b on a.id = b.forum inner join
|
||||||
|
@ -142,7 +142,7 @@ where
|
||||||
match(c.beitrag) against ('+abc' in boolean mode)
|
match(c.beitrag) against ('+abc' in boolean mode)
|
||||||
order by
|
order by
|
||||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||||
ERROR 42S22: Unknown column 'b.betreff' in 'order clause'
|
ERROR 42000: Incorrect usage/placement of 'MATCH()'
|
||||||
select a.text, b.id, b.betreff
|
select a.text, b.id, b.betreff
|
||||||
from
|
from
|
||||||
t2 a inner join t3 b on a.id = b.forum inner join
|
t2 a inner join t3 b on a.id = b.forum inner join
|
||||||
|
@ -158,7 +158,7 @@ where
|
||||||
match(c.beitrag) against ('+abc' in boolean mode)
|
match(c.beitrag) against ('+abc' in boolean mode)
|
||||||
order by
|
order by
|
||||||
match(betreff) against ('+abc' in boolean mode) desc;
|
match(betreff) against ('+abc' in boolean mode) desc;
|
||||||
text id betreff
|
ERROR 42000: Incorrect usage/placement of 'MATCH()'
|
||||||
(select b.id, b.betreff from t3 b) union
|
(select b.id, b.betreff from t3 b) union
|
||||||
(select b.id, b.betreff from t3 b)
|
(select b.id, b.betreff from t3 b)
|
||||||
order by match(betreff) against ('+abc' in boolean mode) desc;
|
order by match(betreff) against ('+abc' in boolean mode) desc;
|
||||||
|
|
|
@ -6907,6 +6907,22 @@ CALL p1();
|
||||||
CALL p1();
|
CALL p1();
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 ( f1 integer, primary key (f1));
|
||||||
|
CREATE TABLE t2 LIKE t1;
|
||||||
|
CREATE TEMPORARY TABLE t3 LIKE t1;
|
||||||
|
CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ;
|
||||||
|
END|
|
||||||
|
CALL p1;
|
||||||
|
ERROR HY000: Can't reopen table: 'A'
|
||||||
|
CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 );
|
||||||
|
DROP TABLE t3;
|
||||||
|
CALL p1;
|
||||||
|
f1
|
||||||
|
CALL p1;
|
||||||
|
f1
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
DROP VIEW t3;
|
||||||
#
|
#
|
||||||
# Bug #46629: Item_in_subselect::val_int(): Assertion `0'
|
# Bug #46629: Item_in_subselect::val_int(): Assertion `0'
|
||||||
# on subquery inside a SP
|
# on subquery inside a SP
|
||||||
|
|
|
@ -1588,3 +1588,66 @@ Warnings:
|
||||||
Note 1003 select '0' AS `a` from `test`.`t1` union select '0' AS `a` from `test`.`t1` order by `a`
|
Note 1003 select '0' AS `a` from `test`.`t1` union select '0' AS `a` from `test`.`t1` order by `a`
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
#
|
||||||
|
# Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY
|
||||||
|
# <any non-const-function>
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
CREATE TABLE t2 (b INT);
|
||||||
|
INSERT INTO t2 VALUES (1),(2);
|
||||||
|
# Should not crash
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
|
||||||
|
2 UNION t1 ALL NULL NULL NULL NULL 2 100.00
|
||||||
|
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (`a` + 12)
|
||||||
|
# Should not crash
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
# Should not crash
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1
|
||||||
|
ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
|
||||||
|
ERROR 42000: Incorrect usage/placement of 'MATCH()'
|
||||||
|
# Should not crash
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1
|
||||||
|
ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
|
||||||
|
ERROR 42000: Incorrect usage/placement of 'MATCH()'
|
||||||
|
# Should not crash
|
||||||
|
(SELECT * FROM t1) UNION (SELECT * FROM t1)
|
||||||
|
ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
# Should not crash
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1
|
||||||
|
ORDER BY (SELECT a FROM t2 WHERE b = 12);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
|
||||||
|
2 UNION t1 ALL NULL NULL NULL NULL 2 100.00
|
||||||
|
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
|
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (select `test`.`t1`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`b` = 12))
|
||||||
|
# Should not crash
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1
|
||||||
|
ORDER BY (SELECT a FROM t2 WHERE b = 12);
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
# Should not crash
|
||||||
|
SELECT * FROM t2 UNION SELECT * FROM t2
|
||||||
|
ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
|
||||||
|
b
|
||||||
|
1
|
||||||
|
2
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
End of 5.1 tests
|
||||||
|
|
|
@ -409,6 +409,21 @@ SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b;
|
||||||
a b
|
a b
|
||||||
2 3
|
2 3
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL);
|
||||||
|
CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11));
|
||||||
|
CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL);
|
||||||
|
INSERT INTO t1 VALUES(10, 10);
|
||||||
|
INSERT INTO t1 VALUES(10, 10);
|
||||||
|
INSERT INTO t2 VALUES(10, 10, 10);
|
||||||
|
INSERT INTO t2 VALUES(10, 10, 10);
|
||||||
|
INSERT INTO t3 VALUES(10, 10);
|
||||||
|
INSERT INTO t3 VALUES(10, 10);
|
||||||
|
SELECT MIN(t2.f1),
|
||||||
|
@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo)
|
||||||
|
FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1;
|
||||||
|
MIN(t2.f1) @bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo)
|
||||||
|
10 NULL
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
CREATE TABLE t1 (i INT);
|
CREATE TABLE t1 (i INT);
|
||||||
CREATE TRIGGER t_after_insert AFTER INSERT ON t1 FOR EACH ROW SET @bug42188 = 10;
|
CREATE TRIGGER t_after_insert AFTER INSERT ON t1 FOR EACH ROW SET @bug42188 = 10;
|
||||||
|
|
|
@ -1061,6 +1061,18 @@ ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL;
|
||||||
--disable_info
|
--disable_info
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux)
|
||||||
|
--echo # or freezes (win) the server
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a TEXT, id INT, b INT);
|
||||||
|
ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -35,6 +35,25 @@ insert into t1 values ('NYC Lib','New York');
|
||||||
select t2.isbn,city,t1.libname,count(t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city,t1.libname;
|
select t2.isbn,city,t1.libname,count(t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city,t1.libname;
|
||||||
select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct t1.libname) > 1;
|
select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct t1.libname) > 1;
|
||||||
select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct concat(t1.libname,'a')) > 1;
|
select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct concat(t1.libname,'a')) > 1;
|
||||||
|
|
||||||
|
select t2.isbn,city,@bar:=t1.libname,count(distinct t1.libname) as a
|
||||||
|
from t3 left join t1 on t3.libname=t1.libname left join t2
|
||||||
|
on t3.isbn=t2.isbn group by city having count(distinct
|
||||||
|
t1.libname) > 1;
|
||||||
|
#
|
||||||
|
# Wrong result, see bug#49872
|
||||||
|
#
|
||||||
|
SELECT @bar;
|
||||||
|
|
||||||
|
select t2.isbn,city,concat(@bar:=t1.libname),count(distinct t1.libname) as a
|
||||||
|
from t3 left join t1 on t3.libname=t1.libname left join t2
|
||||||
|
on t3.isbn=t2.isbn group by city having count(distinct
|
||||||
|
t1.libname) > 1;
|
||||||
|
#
|
||||||
|
# Wrong result, see bug#49872
|
||||||
|
#
|
||||||
|
SELECT @bar;
|
||||||
|
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -80,7 +80,7 @@ CREATE TABLE t3 (
|
||||||
FULLTEXT KEY betreff (betreff)
|
FULLTEXT KEY betreff (betreff)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=996 ;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=996 ;
|
||||||
|
|
||||||
--error 1054
|
--error ER_CANT_USE_OPTION_HERE
|
||||||
select a.text, b.id, b.betreff
|
select a.text, b.id, b.betreff
|
||||||
from
|
from
|
||||||
t2 a inner join t3 b on a.id = b.forum inner join
|
t2 a inner join t3 b on a.id = b.forum inner join
|
||||||
|
@ -100,7 +100,7 @@ group by
|
||||||
order by
|
order by
|
||||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||||
|
|
||||||
--error 1054
|
--error ER_CANT_USE_OPTION_HERE
|
||||||
select a.text, b.id, b.betreff
|
select a.text, b.id, b.betreff
|
||||||
from
|
from
|
||||||
t2 a inner join t3 b on a.id = b.forum inner join
|
t2 a inner join t3 b on a.id = b.forum inner join
|
||||||
|
@ -117,6 +117,7 @@ where
|
||||||
order by
|
order by
|
||||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||||
|
|
||||||
|
--error ER_CANT_USE_OPTION_HERE
|
||||||
select a.text, b.id, b.betreff
|
select a.text, b.id, b.betreff
|
||||||
from
|
from
|
||||||
t2 a inner join t3 b on a.id = b.forum inner join
|
t2 a inner join t3 b on a.id = b.forum inner join
|
||||||
|
|
|
@ -8241,6 +8241,25 @@ while ($tab_count)
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#47649 crash during CALL procedure
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ( f1 integer, primary key (f1));
|
||||||
|
CREATE TABLE t2 LIKE t1;
|
||||||
|
CREATE TEMPORARY TABLE t3 LIKE t1;
|
||||||
|
delimiter |;
|
||||||
|
CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ;
|
||||||
|
END|
|
||||||
|
delimiter ;|
|
||||||
|
--error ER_CANT_REOPEN_TABLE
|
||||||
|
CALL p1;
|
||||||
|
CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 );
|
||||||
|
DROP TABLE t3;
|
||||||
|
CALL p1;
|
||||||
|
CALL p1;
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
DROP TABLE t1, t2;
|
||||||
|
DROP VIEW t3;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Bug #46629: Item_in_subselect::val_int(): Assertion `0'
|
--echo # Bug #46629: Item_in_subselect::val_int(): Assertion `0'
|
||||||
|
|
|
@ -1102,3 +1102,56 @@ DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY
|
||||||
|
--echo # <any non-const-function>
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
CREATE TABLE t2 (b INT);
|
||||||
|
INSERT INTO t2 VALUES (1),(2);
|
||||||
|
|
||||||
|
--echo # Should not crash
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12;
|
||||||
|
|
||||||
|
--echo # Should not crash
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12;
|
||||||
|
|
||||||
|
|
||||||
|
--echo # Should not crash
|
||||||
|
--error ER_CANT_USE_OPTION_HERE
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1
|
||||||
|
ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
|
||||||
|
|
||||||
|
--echo # Should not crash
|
||||||
|
--error ER_CANT_USE_OPTION_HERE
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1
|
||||||
|
ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
|
||||||
|
|
||||||
|
--echo # Should not crash
|
||||||
|
(SELECT * FROM t1) UNION (SELECT * FROM t1)
|
||||||
|
ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE);
|
||||||
|
|
||||||
|
|
||||||
|
--echo # Should not crash
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1
|
||||||
|
ORDER BY (SELECT a FROM t2 WHERE b = 12);
|
||||||
|
|
||||||
|
--echo # Should not crash
|
||||||
|
SELECT * FROM t1 UNION SELECT * FROM t1
|
||||||
|
ORDER BY (SELECT a FROM t2 WHERE b = 12);
|
||||||
|
|
||||||
|
--echo # Should not crash
|
||||||
|
SELECT * FROM t2 UNION SELECT * FROM t2
|
||||||
|
ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
|
||||||
|
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
|
||||||
|
--echo End of 5.1 tests
|
||||||
|
|
|
@ -295,6 +295,26 @@ SELECT @a, @b;
|
||||||
SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b;
|
SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#47371: reference by same column name
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL);
|
||||||
|
CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11));
|
||||||
|
CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL);
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES(10, 10);
|
||||||
|
INSERT INTO t1 VALUES(10, 10);
|
||||||
|
INSERT INTO t2 VALUES(10, 10, 10);
|
||||||
|
INSERT INTO t2 VALUES(10, 10, 10);
|
||||||
|
INSERT INTO t3 VALUES(10, 10);
|
||||||
|
INSERT INTO t3 VALUES(10, 10);
|
||||||
|
|
||||||
|
SELECT MIN(t2.f1),
|
||||||
|
@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo)
|
||||||
|
FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1;
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -8333,8 +8333,7 @@ uint Field_blob::is_equal(Create_field *new_field)
|
||||||
|
|
||||||
return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
|
return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
|
||||||
&& new_field->charset == field_charset &&
|
&& new_field->charset == field_charset &&
|
||||||
((Field_blob *)new_field->field)->max_data_length() ==
|
new_field->pack_length == pack_length());
|
||||||
max_data_length());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5897,6 +5897,23 @@ const key_map *ha_partition::keys_to_use_for_scanning()
|
||||||
DBUG_RETURN(m_file[0]->keys_to_use_for_scanning());
|
DBUG_RETURN(m_file[0]->keys_to_use_for_scanning());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_PARTS_FOR_OPTIMIZER_CALLS 10
|
||||||
|
/*
|
||||||
|
Prepare start variables for estimating optimizer costs.
|
||||||
|
|
||||||
|
@param[out] num_used_parts Number of partitions after pruning.
|
||||||
|
@param[out] check_min_num Number of partitions to call.
|
||||||
|
@param[out] first first used partition.
|
||||||
|
*/
|
||||||
|
void ha_partition::partitions_optimizer_call_preparations(uint *first,
|
||||||
|
uint *num_used_parts,
|
||||||
|
uint *check_min_num)
|
||||||
|
{
|
||||||
|
*first= bitmap_get_first_set(&(m_part_info->used_partitions));
|
||||||
|
*num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
|
||||||
|
*check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Return time for a scan of the table
|
Return time for a scan of the table
|
||||||
|
@ -5910,43 +5927,67 @@ const key_map *ha_partition::keys_to_use_for_scanning()
|
||||||
|
|
||||||
double ha_partition::scan_time()
|
double ha_partition::scan_time()
|
||||||
{
|
{
|
||||||
double scan_time= 0;
|
double scan_time= 0.0;
|
||||||
handler **file;
|
uint first, part_id, num_used_parts, check_min_num, partitions_called= 0;
|
||||||
DBUG_ENTER("ha_partition::scan_time");
|
DBUG_ENTER("ha_partition::scan_time");
|
||||||
|
|
||||||
for (file= m_file; *file; file++)
|
partitions_optimizer_call_preparations(&first, &num_used_parts, &check_min_num);
|
||||||
if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
|
for (part_id= first; partitions_called < num_used_parts ; part_id++)
|
||||||
scan_time+= (*file)->scan_time();
|
{
|
||||||
|
if (!bitmap_is_set(&(m_part_info->used_partitions), part_id))
|
||||||
|
continue;
|
||||||
|
scan_time+= m_file[part_id]->scan_time();
|
||||||
|
partitions_called++;
|
||||||
|
if (partitions_called >= check_min_num && scan_time != 0.0)
|
||||||
|
{
|
||||||
|
DBUG_RETURN(scan_time *
|
||||||
|
(double) num_used_parts / (double) partitions_called);
|
||||||
|
}
|
||||||
|
}
|
||||||
DBUG_RETURN(scan_time);
|
DBUG_RETURN(scan_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get time to read
|
Estimate rows for records_in_range or estimate_rows_upper_bound.
|
||||||
|
|
||||||
SYNOPSIS
|
@param is_records_in_range call records_in_range instead of
|
||||||
read_time()
|
estimate_rows_upper_bound.
|
||||||
index Index number used
|
@param inx (only for records_in_range) index to use.
|
||||||
ranges Number of ranges
|
@param min_key (only for records_in_range) start of range.
|
||||||
rows Number of rows
|
@param max_key (only for records_in_range) end of range.
|
||||||
|
|
||||||
RETURN VALUE
|
@return Number of rows or HA_POS_ERROR.
|
||||||
time for read
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This will be optimised later to include whether or not the index can
|
|
||||||
be used with partitioning. To achieve we need to add another parameter
|
|
||||||
that specifies how many of the index fields that are bound in the ranges.
|
|
||||||
Possibly added as a new call to handlers.
|
|
||||||
*/
|
*/
|
||||||
|
ha_rows ha_partition::estimate_rows(bool is_records_in_range, uint inx,
|
||||||
double ha_partition::read_time(uint index, uint ranges, ha_rows rows)
|
key_range *min_key, key_range *max_key)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("ha_partition::read_time");
|
ha_rows rows, estimated_rows= 0;
|
||||||
|
uint first, part_id, num_used_parts, check_min_num, partitions_called= 0;
|
||||||
|
DBUG_ENTER("ha_partition::records_in_range");
|
||||||
|
|
||||||
DBUG_RETURN(m_file[0]->read_time(index, ranges, rows));
|
partitions_optimizer_call_preparations(&first, &num_used_parts, &check_min_num);
|
||||||
|
for (part_id= first; partitions_called < num_used_parts ; part_id++)
|
||||||
|
{
|
||||||
|
if (!bitmap_is_set(&(m_part_info->used_partitions), part_id))
|
||||||
|
continue;
|
||||||
|
if (is_records_in_range)
|
||||||
|
rows= m_file[part_id]->records_in_range(inx, min_key, max_key);
|
||||||
|
else
|
||||||
|
rows= m_file[part_id]->estimate_rows_upper_bound();
|
||||||
|
if (rows == HA_POS_ERROR)
|
||||||
|
DBUG_RETURN(HA_POS_ERROR);
|
||||||
|
estimated_rows+= rows;
|
||||||
|
partitions_called++;
|
||||||
|
if (partitions_called >= check_min_num && estimated_rows)
|
||||||
|
{
|
||||||
|
DBUG_RETURN(estimated_rows * num_used_parts / partitions_called);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_RETURN(estimated_rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Find number of records in a range
|
Find number of records in a range
|
||||||
|
|
||||||
|
@ -5974,22 +6015,9 @@ double ha_partition::read_time(uint index, uint ranges, ha_rows rows)
|
||||||
ha_rows ha_partition::records_in_range(uint inx, key_range *min_key,
|
ha_rows ha_partition::records_in_range(uint inx, key_range *min_key,
|
||||||
key_range *max_key)
|
key_range *max_key)
|
||||||
{
|
{
|
||||||
handler **file;
|
|
||||||
ha_rows in_range= 0;
|
|
||||||
DBUG_ENTER("ha_partition::records_in_range");
|
DBUG_ENTER("ha_partition::records_in_range");
|
||||||
|
|
||||||
file= m_file;
|
DBUG_RETURN(estimate_rows(TRUE, inx, min_key, max_key));
|
||||||
do
|
|
||||||
{
|
|
||||||
if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
|
|
||||||
{
|
|
||||||
ha_rows tmp_in_range= (*file)->records_in_range(inx, min_key, max_key);
|
|
||||||
if (tmp_in_range == HA_POS_ERROR)
|
|
||||||
DBUG_RETURN(tmp_in_range);
|
|
||||||
in_range+= tmp_in_range;
|
|
||||||
}
|
|
||||||
} while (*(++file));
|
|
||||||
DBUG_RETURN(in_range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -6005,22 +6033,36 @@ ha_rows ha_partition::records_in_range(uint inx, key_range *min_key,
|
||||||
|
|
||||||
ha_rows ha_partition::estimate_rows_upper_bound()
|
ha_rows ha_partition::estimate_rows_upper_bound()
|
||||||
{
|
{
|
||||||
ha_rows rows, tot_rows= 0;
|
|
||||||
handler **file;
|
|
||||||
DBUG_ENTER("ha_partition::estimate_rows_upper_bound");
|
DBUG_ENTER("ha_partition::estimate_rows_upper_bound");
|
||||||
|
|
||||||
file= m_file;
|
DBUG_RETURN(estimate_rows(FALSE, 0, NULL, NULL));
|
||||||
do
|
}
|
||||||
{
|
|
||||||
if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
|
|
||||||
{
|
/*
|
||||||
rows= (*file)->estimate_rows_upper_bound();
|
Get time to read
|
||||||
if (rows == HA_POS_ERROR)
|
|
||||||
DBUG_RETURN(HA_POS_ERROR);
|
SYNOPSIS
|
||||||
tot_rows+= rows;
|
read_time()
|
||||||
}
|
index Index number used
|
||||||
} while (*(++file));
|
ranges Number of ranges
|
||||||
DBUG_RETURN(tot_rows);
|
rows Number of rows
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
time for read
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This will be optimised later to include whether or not the index can
|
||||||
|
be used with partitioning. To achieve we need to add another parameter
|
||||||
|
that specifies how many of the index fields that are bound in the ranges.
|
||||||
|
Possibly added as a new call to handlers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
double ha_partition::read_time(uint index, uint ranges, ha_rows rows)
|
||||||
|
{
|
||||||
|
DBUG_ENTER("ha_partition::read_time");
|
||||||
|
|
||||||
|
DBUG_RETURN(m_file[0]->read_time(index, ranges, rows));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -552,6 +552,18 @@ public:
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
Helper function to get the minimum number of partitions to use for
|
||||||
|
the optimizer hints/cost calls.
|
||||||
|
*/
|
||||||
|
void partitions_optimizer_call_preparations(uint *num_used_parts,
|
||||||
|
uint *check_min_num,
|
||||||
|
uint *first);
|
||||||
|
ha_rows estimate_rows(bool is_records_in_range, uint inx,
|
||||||
|
key_range *min_key, key_range *max_key);
|
||||||
|
public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
keys_to_use_for_scanning can probably be implemented as the
|
keys_to_use_for_scanning can probably be implemented as the
|
||||||
intersection of all underlying handlers if mixed handlers are used.
|
intersection of all underlying handlers if mixed handlers are used.
|
||||||
|
|
17
sql/item.h
17
sql/item.h
|
@ -984,6 +984,23 @@ public:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find a function of a given type
|
||||||
|
|
||||||
|
@param arg the function type to search (enum Item_func::Functype)
|
||||||
|
@return
|
||||||
|
@retval TRUE the function type we're searching for is found
|
||||||
|
@retval FALSE the function type wasn't found
|
||||||
|
|
||||||
|
@description
|
||||||
|
This function can be used (together with Item::walk()) to find functions
|
||||||
|
in an item tree fragment.
|
||||||
|
*/
|
||||||
|
virtual bool find_function_processor (uchar *arg)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For SP local variable returns pointer to Item representing its
|
For SP local variable returns pointer to Item representing its
|
||||||
current value and pointer to current Item otherwise.
|
current value and pointer to current Item otherwise.
|
||||||
|
|
|
@ -606,7 +606,7 @@ void Item_func::signal_divide_by_null()
|
||||||
|
|
||||||
Item *Item_func::get_tmp_table_item(THD *thd)
|
Item *Item_func::get_tmp_table_item(THD *thd)
|
||||||
{
|
{
|
||||||
if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
|
if (!with_sum_func && !const_item())
|
||||||
return new Item_field(result_field);
|
return new Item_field(result_field);
|
||||||
return copy_or_same(thd);
|
return copy_or_same(thd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,11 @@ public:
|
||||||
{
|
{
|
||||||
return has_timestamp_args();
|
return has_timestamp_args();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool find_function_processor (uchar *arg)
|
||||||
|
{
|
||||||
|
return functype() == *(Functype *) arg;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2806,8 +2806,15 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
|
||||||
m_lex->mark_as_requiring_prelocking(NULL);
|
m_lex->mark_as_requiring_prelocking(NULL);
|
||||||
}
|
}
|
||||||
thd->rollback_item_tree_changes();
|
thd->rollback_item_tree_changes();
|
||||||
/* Update the state of the active arena. */
|
/*
|
||||||
thd->stmt_arena->state= Query_arena::EXECUTED;
|
Update the state of the active arena if no errors on
|
||||||
|
open_tables stage.
|
||||||
|
*/
|
||||||
|
if (!res || !thd->is_error() ||
|
||||||
|
(thd->main_da.sql_errno() != ER_CANT_REOPEN_TABLE &&
|
||||||
|
thd->main_da.sql_errno() != ER_NO_SUCH_TABLE &&
|
||||||
|
thd->main_da.sql_errno() != ER_UPDATE_TABLE_USED))
|
||||||
|
thd->stmt_arena->state= Query_arena::EXECUTED;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Merge here with the saved parent's values
|
Merge here with the saved parent's values
|
||||||
|
|
|
@ -523,7 +523,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
||||||
thd->lex->allow_sum_func= save_allow_sum_func;
|
thd->lex->allow_sum_func= save_allow_sum_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!thd->lex->view_prepare_mode)
|
if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE))
|
||||||
{
|
{
|
||||||
Item_subselect *subselect;
|
Item_subselect *subselect;
|
||||||
/* Is it subselect? */
|
/* Is it subselect? */
|
||||||
|
|
|
@ -335,6 +335,35 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Disable the usage of fulltext searches in the last union branch.
|
||||||
|
This is a temporary 5.x limitation because of the way the fulltext
|
||||||
|
search functions are handled by the optimizer.
|
||||||
|
This is manifestation of the more general problems of "taking away"
|
||||||
|
parts of a SELECT statement post-fix_fields(). This is generally not
|
||||||
|
doable since various flags are collected in various places (e.g.
|
||||||
|
SELECT_LEX) that carry information about the presence of certain
|
||||||
|
expressions or constructs in the parts of the query.
|
||||||
|
When part of the query is taken away it's not clear how to "divide"
|
||||||
|
the meaning of these accumulated flags and what to carry over to the
|
||||||
|
recipient query (SELECT_LEX).
|
||||||
|
*/
|
||||||
|
if (global_parameters->ftfunc_list->elements &&
|
||||||
|
global_parameters->order_list.elements &&
|
||||||
|
global_parameters != fake_select_lex)
|
||||||
|
{
|
||||||
|
ORDER *ord;
|
||||||
|
Item_func::Functype ft= Item_func::FT_FUNC;
|
||||||
|
for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next)
|
||||||
|
if ((*ord->item)->walk (&Item::find_function_processor, FALSE,
|
||||||
|
(uchar *) &ft))
|
||||||
|
{
|
||||||
|
my_error (ER_CANT_USE_OPTION_HERE, MYF(0), "MATCH()");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
create_options= (first_sl->options | thd_arg->options |
|
create_options= (first_sl->options | thd_arg->options |
|
||||||
TMP_TABLE_ALL_COLUMNS);
|
TMP_TABLE_ALL_COLUMNS);
|
||||||
/*
|
/*
|
||||||
|
@ -669,7 +698,7 @@ bool st_select_lex_unit::cleanup()
|
||||||
{
|
{
|
||||||
ORDER *ord;
|
ORDER *ord;
|
||||||
for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next)
|
for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next)
|
||||||
(*ord->item)->cleanup();
|
(*ord->item)->walk (&Item::cleanup_processor, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,11 @@
|
||||||
#include <my_global.h>
|
#include <my_global.h>
|
||||||
#include "m_string.h"
|
#include "m_string.h"
|
||||||
|
|
||||||
#ifdef BAD_STRING_COMPILER
|
#ifdef strmov
|
||||||
#undef strmov
|
#undef strmov
|
||||||
#define strmov strmov_overlapp
|
#define strmov strmov_overlapp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef strmov
|
|
||||||
|
|
||||||
#if !defined(MC68000) && !defined(DS90)
|
#if !defined(MC68000) && !defined(DS90)
|
||||||
|
|
||||||
char *strmov(register char *dst, register const char *src)
|
char *strmov(register char *dst, register const char *src)
|
||||||
|
@ -53,5 +51,3 @@ char *strmov(dst, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* strmov */
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue