mirror of
https://github.com/MariaDB/server.git
synced 2025-01-28 09:44:17 +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
client
include
mysql-test
r
t
sql
field.ccha_partition.ccha_partition.hitem.hitem_func.ccitem_func.hsp_head.ccsql_select.ccsql_union.cc
strings
|
@ -4192,7 +4192,7 @@ char *get_arg(char *line, my_bool get_next_arg)
|
|||
if (*ptr == '\\' && ptr[1]) // escaped character
|
||||
{
|
||||
// Remove the backslash
|
||||
strmov(ptr, ptr+1);
|
||||
strmov_overlapp(ptr, ptr+1);
|
||||
}
|
||||
else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype))
|
||||
{
|
||||
|
|
|
@ -95,9 +95,7 @@ extern char NEAR _dig_vec_lower[];
|
|||
/* Defined in strtod.c */
|
||||
extern const double log_10[309];
|
||||
|
||||
#ifdef BAD_STRING_COMPILER
|
||||
#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1)
|
||||
#else
|
||||
#ifndef strmov
|
||||
#define strmov_overlapp(A,B) strmov(A,B)
|
||||
#define strmake_overlapp(A,B,C) strmake(A,B,C)
|
||||
#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 char *strkey(char *dst,char *head,char *tail,char *flags);
|
||||
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
|
||||
extern char *strmov(char *dst,const char *src);
|
||||
#else
|
||||
extern char *strmov_overlapp(char *dst,const char *src);
|
||||
#endif
|
||||
extern char *strnmov(char *dst,const char *src,size_t n);
|
||||
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
|
||||
info: Records: 0 Duplicates: 0 Warnings: 0
|
||||
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
|
||||
CREATE TABLE t1(c CHAR(10),
|
||||
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
|
||||
007 Berkeley Berkeley Public1 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;
|
||||
create table t1 (f1 int);
|
||||
insert into t1 values (1);
|
||||
|
|
|
@ -126,7 +126,7 @@ group by
|
|||
a.text, b.id, b.betreff
|
||||
order by
|
||||
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
|
||||
from
|
||||
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)
|
||||
order by
|
||||
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
|
||||
from
|
||||
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)
|
||||
order by
|
||||
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)
|
||||
order by match(betreff) against ('+abc' in boolean mode) desc;
|
||||
|
|
|
@ -6907,6 +6907,22 @@ CALL p1();
|
|||
CALL p1();
|
||||
DROP PROCEDURE p1;
|
||||
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'
|
||||
# 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`
|
||||
DROP TABLE t1;
|
||||
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
|
||||
2 3
|
||||
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
|
||||
CREATE TABLE t1 (i INT);
|
||||
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
|
||||
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
|
||||
|
||||
#
|
||||
|
|
|
@ -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(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,@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;
|
||||
|
||||
#
|
||||
|
|
|
@ -80,7 +80,7 @@ CREATE TABLE t3 (
|
|||
FULLTEXT KEY betreff (betreff)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=996 ;
|
||||
|
||||
--error 1054
|
||||
--error ER_CANT_USE_OPTION_HERE
|
||||
select a.text, b.id, b.betreff
|
||||
from
|
||||
t2 a inner join t3 b on a.id = b.forum inner join
|
||||
|
@ -100,7 +100,7 @@ group by
|
|||
order by
|
||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||
|
||||
--error 1054
|
||||
--error ER_CANT_USE_OPTION_HERE
|
||||
select a.text, b.id, b.betreff
|
||||
from
|
||||
t2 a inner join t3 b on a.id = b.forum inner join
|
||||
|
@ -117,6 +117,7 @@ where
|
|||
order by
|
||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||
|
||||
--error ER_CANT_USE_OPTION_HERE
|
||||
select a.text, b.id, b.betreff
|
||||
from
|
||||
t2 a inner join t3 b on a.id = b.forum inner join
|
||||
|
|
|
@ -8241,6 +8241,25 @@ while ($tab_count)
|
|||
DROP PROCEDURE p1;
|
||||
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 # Bug #46629: Item_in_subselect::val_int(): Assertion `0'
|
||||
|
|
|
@ -1102,3 +1102,56 @@ DROP TABLE t1;
|
|||
|
||||
|
||||
--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;
|
||||
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
|
||||
|
||||
#
|
||||
|
|
|
@ -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()))
|
||||
&& new_field->charset == field_charset &&
|
||||
((Field_blob *)new_field->field)->max_data_length() ==
|
||||
max_data_length());
|
||||
new_field->pack_length == pack_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());
|
||||
}
|
||||
|
||||
#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
|
||||
|
@ -5910,43 +5927,67 @@ const key_map *ha_partition::keys_to_use_for_scanning()
|
|||
|
||||
double ha_partition::scan_time()
|
||||
{
|
||||
double scan_time= 0;
|
||||
handler **file;
|
||||
double scan_time= 0.0;
|
||||
uint first, part_id, num_used_parts, check_min_num, partitions_called= 0;
|
||||
DBUG_ENTER("ha_partition::scan_time");
|
||||
|
||||
for (file= m_file; *file; file++)
|
||||
if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
|
||||
scan_time+= (*file)->scan_time();
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get time to read
|
||||
Estimate rows for records_in_range or estimate_rows_upper_bound.
|
||||
|
||||
SYNOPSIS
|
||||
read_time()
|
||||
index Index number used
|
||||
ranges Number of ranges
|
||||
rows Number of rows
|
||||
@param is_records_in_range call records_in_range instead of
|
||||
estimate_rows_upper_bound.
|
||||
@param inx (only for records_in_range) index to use.
|
||||
@param min_key (only for records_in_range) start of range.
|
||||
@param max_key (only for records_in_range) end of range.
|
||||
|
||||
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.
|
||||
@return Number of rows or HA_POS_ERROR.
|
||||
*/
|
||||
|
||||
double ha_partition::read_time(uint index, uint ranges, ha_rows rows)
|
||||
ha_rows ha_partition::estimate_rows(bool is_records_in_range, uint inx,
|
||||
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
|
||||
|
||||
|
@ -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,
|
||||
key_range *max_key)
|
||||
{
|
||||
handler **file;
|
||||
ha_rows in_range= 0;
|
||||
DBUG_ENTER("ha_partition::records_in_range");
|
||||
|
||||
file= m_file;
|
||||
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);
|
||||
DBUG_RETURN(estimate_rows(TRUE, inx, min_key, max_key));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 rows, tot_rows= 0;
|
||||
handler **file;
|
||||
DBUG_ENTER("ha_partition::estimate_rows_upper_bound");
|
||||
|
||||
file= m_file;
|
||||
do
|
||||
{
|
||||
if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file)))
|
||||
{
|
||||
rows= (*file)->estimate_rows_upper_bound();
|
||||
if (rows == HA_POS_ERROR)
|
||||
DBUG_RETURN(HA_POS_ERROR);
|
||||
tot_rows+= rows;
|
||||
}
|
||||
} while (*(++file));
|
||||
DBUG_RETURN(tot_rows);
|
||||
DBUG_RETURN(estimate_rows(FALSE, 0, NULL, NULL));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get time to read
|
||||
|
||||
SYNOPSIS
|
||||
read_time()
|
||||
index Index number used
|
||||
ranges Number of ranges
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
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)
|
||||
{
|
||||
if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
|
||||
if (!with_sum_func && !const_item())
|
||||
return new Item_field(result_field);
|
||||
return copy_or_same(thd);
|
||||
}
|
||||
|
|
|
@ -215,6 +215,11 @@ public:
|
|||
{
|
||||
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);
|
||||
}
|
||||
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
|
||||
|
|
|
@ -523,7 +523,7 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||
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;
|
||||
/* 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 |
|
||||
TMP_TABLE_ALL_COLUMNS);
|
||||
/*
|
||||
|
@ -669,7 +698,7 @@ bool st_select_lex_unit::cleanup()
|
|||
{
|
||||
ORDER *ord;
|
||||
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 "m_string.h"
|
||||
|
||||
#ifdef BAD_STRING_COMPILER
|
||||
#ifdef strmov
|
||||
#undef strmov
|
||||
#define strmov strmov_overlapp
|
||||
#endif
|
||||
|
||||
#ifndef strmov
|
||||
|
||||
#if !defined(MC68000) && !defined(DS90)
|
||||
|
||||
char *strmov(register char *dst, register const char *src)
|
||||
|
@ -53,5 +51,3 @@ char *strmov(dst, src)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* strmov */
|
||||
|
|
Loading…
Add table
Reference in a new issue