mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 10:31:54 +01:00
Merge bk@192.168.21.1:mysql-5.0
into mysql.com:/d2/hf/mrg/mysql-5.0-opt
This commit is contained in:
commit
37a9575b2e
23 changed files with 403 additions and 23 deletions
|
@ -351,6 +351,12 @@ DROP TABLE t1;
|
||||||
select isnull(date(NULL)), isnull(cast(NULL as DATE));
|
select isnull(date(NULL)), isnull(cast(NULL as DATE));
|
||||||
isnull(date(NULL)) isnull(cast(NULL as DATE))
|
isnull(date(NULL)) isnull(cast(NULL as DATE))
|
||||||
1 1
|
1 1
|
||||||
|
SELECT CAST(cast('01-01-01' as date) AS UNSIGNED);
|
||||||
|
CAST(cast('01-01-01' as date) AS UNSIGNED)
|
||||||
|
20010101
|
||||||
|
SELECT CAST(cast('01-01-01' as date) AS SIGNED);
|
||||||
|
CAST(cast('01-01-01' as date) AS SIGNED)
|
||||||
|
20010101
|
||||||
End of 4.1 tests
|
End of 4.1 tests
|
||||||
select cast('1.2' as decimal(3,2));
|
select cast('1.2' as decimal(3,2));
|
||||||
cast('1.2' as decimal(3,2))
|
cast('1.2' as decimal(3,2))
|
||||||
|
|
|
@ -391,6 +391,56 @@ i i i
|
||||||
2 NULL 4
|
2 NULL 4
|
||||||
2 2 2
|
2 2 2
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
CREATE TABLE t1 (a int, b int default 0, c int default 1);
|
||||||
|
INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8);
|
||||||
|
INSERT INTO t1 (a) SELECT a + 8 FROM t1;
|
||||||
|
INSERT INTO t1 (a) SELECT a + 16 FROM t1;
|
||||||
|
CREATE TABLE t2 (a int, d int, e int default 0);
|
||||||
|
INSERT INTO t2 (a, d) VALUES (1,1),(2,2),(3,3),(4,4);
|
||||||
|
INSERT INTO t2 (a, d) SELECT a+4, a+4 FROM t2;
|
||||||
|
INSERT INTO t2 (a, d) SELECT a+8, a+8 FROM t2;
|
||||||
|
EXPLAIN
|
||||||
|
SELECT STRAIGHT_JOIN t2.e FROM t1,t2 WHERE t2.d=1 AND t1.b=t2.e
|
||||||
|
ORDER BY t1.b, t1.c;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 32 Using temporary; Using filesort
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 16 Using where
|
||||||
|
SELECT STRAIGHT_JOIN t2.e FROM t1,t2 WHERE t2.d=1 AND t1.b=t2.e
|
||||||
|
ORDER BY t1.b, t1.c;
|
||||||
|
e
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
DROP TABLE t1,t2;
|
||||||
create table t1 (c int, b int);
|
create table t1 (c int, b int);
|
||||||
create table t2 (a int, b int);
|
create table t2 (a int, b int);
|
||||||
create table t3 (b int, c int);
|
create table t3 (b int, c int);
|
||||||
|
|
|
@ -1214,3 +1214,28 @@ SELECT * FROM t1 LEFT JOIN t2 USING(f1) WHERE f1='Bla';
|
||||||
f1 f2 f3
|
f1 f2 f3
|
||||||
bla blah sheep
|
bla blah sheep
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
CREATE TABLE t1 (id int PRIMARY KEY, a varchar(8));
|
||||||
|
CREATE TABLE t2 (id int NOT NULL, b int NOT NULL, INDEX idx(id));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1,'aaaaaaa'), (5,'eeeeeee'), (4,'ddddddd'), (2,'bbbbbbb'), (3,'ccccccc');
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(3,10), (2,20), (5,30), (3,20), (5,10), (3,40), (3,30), (2,10), (2,40);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
|
||||||
|
1 SIMPLE t2 ref idx idx 4 test.t1.id 2 Using where; Not exists
|
||||||
|
flush status;
|
||||||
|
SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL;
|
||||||
|
id a
|
||||||
|
1 aaaaaaa
|
||||||
|
4 ddddddd
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 5
|
||||||
|
Handler_read_next 0
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 0
|
||||||
|
Handler_read_rnd_next 6
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
Binary file not shown.
|
@ -690,12 +690,12 @@ END|
|
||||||
CALL p1(NOW());
|
CALL p1(NOW());
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE "t1" (
|
t1 CREATE TABLE "t1" (
|
||||||
"x" varbinary(19) default NULL
|
"x" datetime default NULL
|
||||||
)
|
)
|
||||||
CALL p1('test');
|
CALL p1('test');
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE "t1" (
|
t1 CREATE TABLE "t1" (
|
||||||
"x" varbinary(19) default NULL
|
"x" datetime default NULL
|
||||||
)
|
)
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1264 Out of range value adjusted for column 'x' at row 1
|
Warning 1264 Out of range value adjusted for column 'x' at row 1
|
||||||
|
|
|
@ -4034,4 +4034,11 @@ SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
|
||||||
FROM t1;
|
FROM t1;
|
||||||
ERROR HY000: Invalid use of group function
|
ERROR HY000: Invalid use of group function
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
CREATE TABLE t1 (a int, b int, KEY (a));
|
||||||
|
INSERT INTO t1 VALUES (1,1),(2,1);
|
||||||
|
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
|
||||||
|
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
|
|
|
@ -264,3 +264,33 @@ f2
|
||||||
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
|
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
|
||||||
1
|
1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
select least(cast('01-01-01' as date), '01-01-02');
|
||||||
|
least(cast('01-01-01' as date), '01-01-02')
|
||||||
|
2001-01-01
|
||||||
|
select greatest(cast('01-01-01' as date), '01-01-02');
|
||||||
|
greatest(cast('01-01-01' as date), '01-01-02')
|
||||||
|
01-01-02
|
||||||
|
select least(cast('01-01-01' as date), '01-01-02') + 0;
|
||||||
|
least(cast('01-01-01' as date), '01-01-02') + 0
|
||||||
|
20010101
|
||||||
|
select greatest(cast('01-01-01' as date), '01-01-02') + 0;
|
||||||
|
greatest(cast('01-01-01' as date), '01-01-02') + 0
|
||||||
|
20010102
|
||||||
|
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
|
||||||
|
least(cast('01-01-01' as datetime), '01-01-02') + 0
|
||||||
|
20010101000000
|
||||||
|
DROP PROCEDURE IF EXISTS test27759 ;
|
||||||
|
CREATE PROCEDURE test27759()
|
||||||
|
BEGIN
|
||||||
|
declare v_a date default '2007-4-10';
|
||||||
|
declare v_b date default '2007-4-11';
|
||||||
|
declare v_c datetime default '2004-4-9 0:0:0';
|
||||||
|
select v_a as a,v_b as b,
|
||||||
|
least( v_a, v_b ) as a_then_b,
|
||||||
|
least( v_b, v_a ) as b_then_a,
|
||||||
|
least( v_c, v_a ) as c_then_a;
|
||||||
|
END;|
|
||||||
|
call test27759();
|
||||||
|
a b a_then_b b_then_a c_then_a
|
||||||
|
2007-04-10 2007-04-11 2007-04-10 2007-04-10 2004-04-09 00:00:00
|
||||||
|
drop procedure test27759;
|
||||||
|
|
|
@ -182,6 +182,12 @@ DROP TABLE t1;
|
||||||
|
|
||||||
select isnull(date(NULL)), isnull(cast(NULL as DATE));
|
select isnull(date(NULL)), isnull(cast(NULL as DATE));
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#23656: Wrong result of CAST from DATE to int
|
||||||
|
#
|
||||||
|
SELECT CAST(cast('01-01-01' as date) AS UNSIGNED);
|
||||||
|
SELECT CAST(cast('01-01-01' as date) AS SIGNED);
|
||||||
|
|
||||||
--echo End of 4.1 tests
|
--echo End of 4.1 tests
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -333,6 +333,30 @@ select t1.i,t2.i,t3.i from t2 natural right join t3,t1 order by t1.i,t2.i,t3.i;
|
||||||
select t1.i,t2.i,t3.i from t2 right join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i;
|
select t1.i,t2.i,t3.i from t2 right join t3 on (t2.i=t3.i),t1 order by t1.i,t2.i,t3.i;
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #27531: Query performance degredation in 4.1.22 and greater
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int, b int default 0, c int default 1);
|
||||||
|
|
||||||
|
INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8);
|
||||||
|
INSERT INTO t1 (a) SELECT a + 8 FROM t1;
|
||||||
|
INSERT INTO t1 (a) SELECT a + 16 FROM t1;
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a int, d int, e int default 0);
|
||||||
|
|
||||||
|
INSERT INTO t2 (a, d) VALUES (1,1),(2,2),(3,3),(4,4);
|
||||||
|
INSERT INTO t2 (a, d) SELECT a+4, a+4 FROM t2;
|
||||||
|
INSERT INTO t2 (a, d) SELECT a+8, a+8 FROM t2;
|
||||||
|
|
||||||
|
# should use join cache
|
||||||
|
EXPLAIN
|
||||||
|
SELECT STRAIGHT_JOIN t2.e FROM t1,t2 WHERE t2.d=1 AND t1.b=t2.e
|
||||||
|
ORDER BY t1.b, t1.c;
|
||||||
|
SELECT STRAIGHT_JOIN t2.e FROM t1,t2 WHERE t2.d=1 AND t1.b=t2.e
|
||||||
|
ORDER BY t1.b, t1.c;
|
||||||
|
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -825,3 +825,23 @@ SELECT * FROM t1 LEFT JOIN t2 USING(f1) WHERE f1='bla';
|
||||||
SELECT * FROM t1 LEFT JOIN t2 USING(f1) WHERE f1='Bla';
|
SELECT * FROM t1 LEFT JOIN t2 USING(f1) WHERE f1='Bla';
|
||||||
|
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug 28188: 'not exists' optimization for outer joins
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (id int PRIMARY KEY, a varchar(8));
|
||||||
|
CREATE TABLE t2 (id int NOT NULL, b int NOT NULL, INDEX idx(id));
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1,'aaaaaaa'), (5,'eeeeeee'), (4,'ddddddd'), (2,'bbbbbbb'), (3,'ccccccc');
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(3,10), (2,20), (5,30), (3,20), (5,10), (3,40), (3,30), (2,10), (2,40);
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL;
|
||||||
|
|
||||||
|
flush status;
|
||||||
|
SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL;
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
|
@ -96,3 +96,38 @@ create table t1(a int);
|
||||||
eval select * into outfile "$MYSQL_TEST_DIR/outfile-test1" from t1;
|
eval select * into outfile "$MYSQL_TEST_DIR/outfile-test1" from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#28181 Access denied to 'information_schema when
|
||||||
|
# select into out file (regression)
|
||||||
|
#
|
||||||
|
create database mysqltest;
|
||||||
|
create user user_1@localhost;
|
||||||
|
grant all on mysqltest.* to user_1@localhost;
|
||||||
|
connect (con28181_1,localhost,user_1,,mysqltest);
|
||||||
|
|
||||||
|
--error 1044
|
||||||
|
eval select schema_name
|
||||||
|
into outfile "../tmp/outfile-test.4"
|
||||||
|
fields terminated by ',' optionally enclosed by '"'
|
||||||
|
lines terminated by '\n'
|
||||||
|
from information_schema.schemata
|
||||||
|
where schema_name like 'mysqltest';
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
grant file on *.* to user_1@localhost;
|
||||||
|
|
||||||
|
connect (con28181_2,localhost,user_1,,mysqltest);
|
||||||
|
eval select schema_name
|
||||||
|
into outfile "../tmp/outfile-test.4"
|
||||||
|
fields terminated by ',' optionally enclosed by '"'
|
||||||
|
lines terminated by '\n'
|
||||||
|
from information_schema.schemata
|
||||||
|
where schema_name like 'mysqltest';
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
--exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.4
|
||||||
|
use test;
|
||||||
|
revoke all privileges on *.* from user_1@localhost;
|
||||||
|
drop user user_1@localhost;
|
||||||
|
drop database mysqltest;
|
||||||
|
|
||||||
|
|
|
@ -2874,4 +2874,12 @@ FROM t1;
|
||||||
|
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #27807: Server crash when executing subquery with EXPLAIN
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int, b int, KEY (a));
|
||||||
|
INSERT INTO t1 VALUES (1,1),(2,1);
|
||||||
|
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
|
|
@ -178,3 +178,29 @@ select f2, f3 from t1 where '01-03-10' between f2 and f3;
|
||||||
select f2 from t1 where DATE(f2) between "2001-4-15" AND "01-4-15";
|
select f2 from t1 where DATE(f2) between "2001-4-15" AND "01-4-15";
|
||||||
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
|
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#27759: Wrong DATE/DATETIME comparison in LEAST()/GREATEST() functions.
|
||||||
|
#
|
||||||
|
select least(cast('01-01-01' as date), '01-01-02');
|
||||||
|
select greatest(cast('01-01-01' as date), '01-01-02');
|
||||||
|
select least(cast('01-01-01' as date), '01-01-02') + 0;
|
||||||
|
select greatest(cast('01-01-01' as date), '01-01-02') + 0;
|
||||||
|
select least(cast('01-01-01' as datetime), '01-01-02') + 0;
|
||||||
|
--disable_warnings
|
||||||
|
DROP PROCEDURE IF EXISTS test27759 ;
|
||||||
|
--enable_warnings
|
||||||
|
DELIMITER |;
|
||||||
|
CREATE PROCEDURE test27759()
|
||||||
|
BEGIN
|
||||||
|
declare v_a date default '2007-4-10';
|
||||||
|
declare v_b date default '2007-4-11';
|
||||||
|
declare v_c datetime default '2004-4-9 0:0:0';
|
||||||
|
select v_a as a,v_b as b,
|
||||||
|
least( v_a, v_b ) as a_then_b,
|
||||||
|
least( v_b, v_a ) as b_then_a,
|
||||||
|
least( v_c, v_a ) as c_then_a;
|
||||||
|
END;|
|
||||||
|
DELIMITER ;|
|
||||||
|
call test27759();
|
||||||
|
drop procedure test27759;
|
||||||
|
|
|
@ -1011,6 +1011,7 @@ Item_splocal::Item_splocal(const LEX_STRING &sp_var_name,
|
||||||
maybe_null= TRUE;
|
maybe_null= TRUE;
|
||||||
|
|
||||||
m_type= sp_map_item_type(sp_var_type);
|
m_type= sp_map_item_type(sp_var_type);
|
||||||
|
m_field_type= sp_var_type;
|
||||||
m_result_type= sp_map_result_type(sp_var_type);
|
m_result_type= sp_map_result_type(sp_var_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -946,7 +946,7 @@ class Item_splocal :public Item_sp_variable,
|
||||||
|
|
||||||
Type m_type;
|
Type m_type;
|
||||||
Item_result m_result_type;
|
Item_result m_result_type;
|
||||||
|
enum_field_types m_field_type;
|
||||||
public:
|
public:
|
||||||
/*
|
/*
|
||||||
Position of this reference to SP variable in the statement (the
|
Position of this reference to SP variable in the statement (the
|
||||||
|
@ -978,6 +978,7 @@ public:
|
||||||
|
|
||||||
inline enum Type type() const;
|
inline enum Type type() const;
|
||||||
inline Item_result result_type() const;
|
inline Item_result result_type() const;
|
||||||
|
inline enum_field_types field_type() const { return m_field_type; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
|
||||||
|
|
|
@ -745,7 +745,7 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
|
||||||
obtained value
|
obtained value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ulonglong
|
ulonglong
|
||||||
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
|
get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
|
||||||
Item *warn_item, bool *is_null)
|
Item *warn_item, bool *is_null)
|
||||||
{
|
{
|
||||||
|
@ -781,7 +781,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
|
||||||
MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME;
|
MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME;
|
||||||
value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
|
value= get_date_from_str(thd, str, t_type, warn_item->name, &error);
|
||||||
}
|
}
|
||||||
if (item->const_item())
|
if (item->const_item() && cache_arg)
|
||||||
{
|
{
|
||||||
Item_cache_int *cache= new Item_cache_int();
|
Item_cache_int *cache= new Item_cache_int();
|
||||||
/* Mark the cache as non-const to prevent re-caching. */
|
/* Mark the cache as non-const to prevent re-caching. */
|
||||||
|
|
|
@ -958,7 +958,8 @@ longlong Item_func_signed::val_int()
|
||||||
longlong value;
|
longlong value;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (args[0]->cast_to_int_type() != STRING_RESULT)
|
if (args[0]->cast_to_int_type() != STRING_RESULT ||
|
||||||
|
args[0]->result_as_longlong())
|
||||||
{
|
{
|
||||||
value= args[0]->val_int();
|
value= args[0]->val_int();
|
||||||
null_value= args[0]->null_value;
|
null_value= args[0]->null_value;
|
||||||
|
@ -997,7 +998,8 @@ longlong Item_func_unsigned::val_int()
|
||||||
my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &value);
|
my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
else if (args[0]->cast_to_int_type() != STRING_RESULT)
|
else if (args[0]->cast_to_int_type() != STRING_RESULT ||
|
||||||
|
args[0]->result_as_longlong())
|
||||||
{
|
{
|
||||||
value= args[0]->val_int();
|
value= args[0]->val_int();
|
||||||
null_value= args[0]->null_value;
|
null_value= args[0]->null_value;
|
||||||
|
@ -2161,6 +2163,7 @@ double Item_func_units::val_real()
|
||||||
void Item_func_min_max::fix_length_and_dec()
|
void Item_func_min_max::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
int max_int_part=0;
|
int max_int_part=0;
|
||||||
|
bool datetime_found= FALSE;
|
||||||
decimals=0;
|
decimals=0;
|
||||||
max_length=0;
|
max_length=0;
|
||||||
maybe_null=0;
|
maybe_null=0;
|
||||||
|
@ -2174,18 +2177,88 @@ void Item_func_min_max::fix_length_and_dec()
|
||||||
if (args[i]->maybe_null)
|
if (args[i]->maybe_null)
|
||||||
maybe_null=1;
|
maybe_null=1;
|
||||||
cmp_type=item_cmp_type(cmp_type,args[i]->result_type());
|
cmp_type=item_cmp_type(cmp_type,args[i]->result_type());
|
||||||
|
if (args[i]->result_type() != ROW_RESULT && args[i]->is_datetime())
|
||||||
|
{
|
||||||
|
datetime_found= TRUE;
|
||||||
|
if (!datetime_item || args[i]->field_type() == MYSQL_TYPE_DATETIME)
|
||||||
|
datetime_item= args[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cmp_type == STRING_RESULT)
|
if (cmp_type == STRING_RESULT)
|
||||||
|
{
|
||||||
agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
|
agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
|
||||||
|
if (datetime_found)
|
||||||
|
{
|
||||||
|
thd= current_thd;
|
||||||
|
compare_as_dates= TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT))
|
else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT))
|
||||||
max_length= my_decimal_precision_to_length(max_int_part+decimals, decimals,
|
max_length= my_decimal_precision_to_length(max_int_part+decimals, decimals,
|
||||||
unsigned_flag);
|
unsigned_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compare item arguments in the DATETIME context.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
cmp_datetimes()
|
||||||
|
value [out] found least/greatest DATE/DATETIME value
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Compare item arguments as DATETIME values and return the index of the
|
||||||
|
least/greatest argument in the arguments array.
|
||||||
|
The correct integer DATE/DATETIME value of the found argument is
|
||||||
|
stored to the value pointer, if latter is provided.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 If one of arguments is NULL
|
||||||
|
# index of the least/greatest argument
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint Item_func_min_max::cmp_datetimes(ulonglong *value)
|
||||||
|
{
|
||||||
|
ulonglong min_max;
|
||||||
|
uint min_max_idx= 0;
|
||||||
|
LINT_INIT(min_max);
|
||||||
|
|
||||||
|
for (uint i=0; i < arg_count ; i++)
|
||||||
|
{
|
||||||
|
Item **arg= args + i;
|
||||||
|
bool is_null;
|
||||||
|
ulonglong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null);
|
||||||
|
if ((null_value= args[i]->null_value))
|
||||||
|
return 0;
|
||||||
|
if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
|
||||||
|
{
|
||||||
|
min_max= res;
|
||||||
|
min_max_idx= i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
*value= min_max;
|
||||||
|
if (datetime_item->field_type() == MYSQL_TYPE_DATE)
|
||||||
|
*value/= 1000000L;
|
||||||
|
}
|
||||||
|
return min_max_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String *Item_func_min_max::val_str(String *str)
|
String *Item_func_min_max::val_str(String *str)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
if (compare_as_dates)
|
||||||
|
{
|
||||||
|
String *str_res;
|
||||||
|
uint min_max_idx= cmp_datetimes(NULL);
|
||||||
|
if (null_value)
|
||||||
|
return 0;
|
||||||
|
str_res= args[min_max_idx]->val_str(str);
|
||||||
|
str_res->set_charset(collation.collation);
|
||||||
|
return str_res;
|
||||||
|
}
|
||||||
switch (cmp_type) {
|
switch (cmp_type) {
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
{
|
{
|
||||||
|
@ -2253,6 +2326,12 @@ double Item_func_min_max::val_real()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
double value=0.0;
|
double value=0.0;
|
||||||
|
if (compare_as_dates)
|
||||||
|
{
|
||||||
|
ulonglong result;
|
||||||
|
(void)cmp_datetimes(&result);
|
||||||
|
return (double)result;
|
||||||
|
}
|
||||||
for (uint i=0; i < arg_count ; i++)
|
for (uint i=0; i < arg_count ; i++)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
|
@ -2274,6 +2353,12 @@ longlong Item_func_min_max::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
longlong value=0;
|
longlong value=0;
|
||||||
|
if (compare_as_dates)
|
||||||
|
{
|
||||||
|
ulonglong result;
|
||||||
|
(void)cmp_datetimes(&result);
|
||||||
|
return (longlong)result;
|
||||||
|
}
|
||||||
for (uint i=0; i < arg_count ; i++)
|
for (uint i=0; i < arg_count ; i++)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
|
@ -2297,6 +2382,13 @@ my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
|
||||||
my_decimal tmp_buf, *tmp, *res;
|
my_decimal tmp_buf, *tmp, *res;
|
||||||
LINT_INIT(res);
|
LINT_INIT(res);
|
||||||
|
|
||||||
|
if (compare_as_dates)
|
||||||
|
{
|
||||||
|
ulonglong value;
|
||||||
|
(void)cmp_datetimes(&value);
|
||||||
|
ulonglong2decimal(value, dec);
|
||||||
|
return dec;
|
||||||
|
}
|
||||||
for (uint i=0; i < arg_count ; i++)
|
for (uint i=0; i < arg_count ; i++)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
|
|
|
@ -687,15 +687,23 @@ class Item_func_min_max :public Item_func
|
||||||
Item_result cmp_type;
|
Item_result cmp_type;
|
||||||
String tmp_value;
|
String tmp_value;
|
||||||
int cmp_sign;
|
int cmp_sign;
|
||||||
|
/* TRUE <=> arguments should be compared in the DATETIME context. */
|
||||||
|
bool compare_as_dates;
|
||||||
|
/* An item used for issuing warnings while string to DATETIME conversion. */
|
||||||
|
Item *datetime_item;
|
||||||
|
THD *thd;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list),
|
Item_func_min_max(List<Item> &list,int cmp_sign_arg) :Item_func(list),
|
||||||
cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg) {}
|
cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg), compare_as_dates(FALSE),
|
||||||
|
datetime_item(0) {}
|
||||||
double val_real();
|
double val_real();
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
String *val_str(String *);
|
String *val_str(String *);
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
enum Item_result result_type () const { return cmp_type; }
|
enum Item_result result_type () const { return cmp_type; }
|
||||||
|
uint cmp_datetimes(ulonglong *value);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_func_min :public Item_func_min_max
|
class Item_func_min :public Item_func_min_max
|
||||||
|
|
|
@ -1774,6 +1774,21 @@ int subselect_single_select_engine::exec()
|
||||||
thd->lex->current_select= save_select;
|
thd->lex->current_select= save_select;
|
||||||
DBUG_RETURN(join->error ? join->error : 1);
|
DBUG_RETURN(join->error ? join->error : 1);
|
||||||
}
|
}
|
||||||
|
if (!select_lex->uncacheable && thd->lex->describe &&
|
||||||
|
!(join->select_options & SELECT_DESCRIBE) &&
|
||||||
|
join->need_tmp && item->const_item())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Force join->join_tmp creation, because this subquery will be replaced
|
||||||
|
by a simple select from the materialization temp table by optimize()
|
||||||
|
called by EXPLAIN and we need to preserve the initial query structure
|
||||||
|
so we can display it.
|
||||||
|
*/
|
||||||
|
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
|
||||||
|
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
|
||||||
|
if (join->init_save_join_tab())
|
||||||
|
DBUG_RETURN(1); /* purecov: inspected */
|
||||||
|
}
|
||||||
if (item->engine_changed)
|
if (item->engine_changed)
|
||||||
{
|
{
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
|
@ -1525,6 +1525,8 @@ void make_date(const DATE_TIME_FORMAT *format, const TIME *l_time,
|
||||||
String *str);
|
String *str);
|
||||||
void make_time(const DATE_TIME_FORMAT *format, const TIME *l_time,
|
void make_time(const DATE_TIME_FORMAT *format, const TIME *l_time,
|
||||||
String *str);
|
String *str);
|
||||||
|
ulonglong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
|
||||||
|
Item *warn_item, bool *is_null);
|
||||||
|
|
||||||
int test_if_number(char *str,int *res,bool allow_wildcards);
|
int test_if_number(char *str,int *res,bool allow_wildcards);
|
||||||
void change_byte(byte *,uint,char,char);
|
void change_byte(byte *,uint,char,char);
|
||||||
|
|
|
@ -5261,7 +5261,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
|
||||||
|
|
||||||
if (schema_db)
|
if (schema_db)
|
||||||
{
|
{
|
||||||
if (want_access & ~(SELECT_ACL | EXTRA_ACL))
|
if (!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL) ||
|
||||||
|
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
|
||||||
{
|
{
|
||||||
if (!no_errors)
|
if (!no_errors)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1426,14 +1426,13 @@ JOIN::optimize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (select_lex->uncacheable && !is_top_level_join())
|
/*
|
||||||
{
|
If this join belongs to an uncacheable subquery save
|
||||||
/* If this join belongs to an uncacheable subquery */
|
the original join
|
||||||
if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
|
*/
|
||||||
DBUG_RETURN(-1);
|
if (select_lex->uncacheable && !is_top_level_join() &&
|
||||||
error= 0; // Ensure that tmp_join.error= 0
|
init_save_join_tab())
|
||||||
restore_tmp();
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error= 0;
|
error= 0;
|
||||||
|
@ -1495,6 +1494,27 @@ JOIN::reinit()
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Save the original join layout
|
||||||
|
|
||||||
|
@details Saves the original join layout so it can be reused in
|
||||||
|
re-execution and for EXPLAIN.
|
||||||
|
|
||||||
|
@return Operation status
|
||||||
|
@retval 0 success.
|
||||||
|
@retval 1 error occurred.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
JOIN::init_save_join_tab()
|
||||||
|
{
|
||||||
|
if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
|
||||||
|
return 1; /* purecov: inspected */
|
||||||
|
error= 0; // Ensure that tmp_join.error= 0
|
||||||
|
restore_tmp();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
JOIN::save_join_tab()
|
JOIN::save_join_tab()
|
||||||
|
@ -5980,11 +6000,14 @@ make_join_readinfo(JOIN *join, ulonglong options)
|
||||||
disable join cache because it will change the ordering of the results.
|
disable join cache because it will change the ordering of the results.
|
||||||
Code handles sort table that is at any location (not only first after
|
Code handles sort table that is at any location (not only first after
|
||||||
the const tables) despite the fact that it's currently prohibited.
|
the const tables) despite the fact that it's currently prohibited.
|
||||||
|
We must disable join cache if the first non-const table alone is
|
||||||
|
ordered. If there is a temp table the ordering is done as a last
|
||||||
|
operation and doesn't prevent join cache usage.
|
||||||
*/
|
*/
|
||||||
if (!ordered_set &&
|
if (!ordered_set && !join->need_tmp &&
|
||||||
(table == join->sort_by_table &&
|
((table == join->sort_by_table &&
|
||||||
(!join->order || join->skip_sort_order)) ||
|
(!join->order || join->skip_sort_order)) ||
|
||||||
(join->sort_by_table == (TABLE *) 1 && i != join->const_tables))
|
(join->sort_by_table == (TABLE *) 1 && i != join->const_tables)))
|
||||||
ordered_set= 1;
|
ordered_set= 1;
|
||||||
|
|
||||||
switch (tab->type) {
|
switch (tab->type) {
|
||||||
|
@ -10526,7 +10549,6 @@ static enum_nested_loop_state
|
||||||
evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
|
evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
|
||||||
int error, my_bool *report_error)
|
int error, my_bool *report_error)
|
||||||
{
|
{
|
||||||
bool not_exists_optimize= join_tab->table->reginfo.not_exists_optimize;
|
|
||||||
bool not_used_in_distinct=join_tab->not_used_in_distinct;
|
bool not_used_in_distinct=join_tab->not_used_in_distinct;
|
||||||
ha_rows found_records=join->found_records;
|
ha_rows found_records=join->found_records;
|
||||||
COND *select_cond= join_tab->select_cond;
|
COND *select_cond= join_tab->select_cond;
|
||||||
|
@ -10563,6 +10585,8 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
|
||||||
first_unmatched->found= 1;
|
first_unmatched->found= 1;
|
||||||
for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
|
for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
|
||||||
{
|
{
|
||||||
|
if (tab->table->reginfo.not_exists_optimize)
|
||||||
|
return NESTED_LOOP_NO_MORE_ROWS;
|
||||||
/* Check all predicates that has just been activated. */
|
/* Check all predicates that has just been activated. */
|
||||||
/*
|
/*
|
||||||
Actually all predicates non-guarded by first_unmatched->found
|
Actually all predicates non-guarded by first_unmatched->found
|
||||||
|
@ -10608,8 +10632,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
enum enum_nested_loop_state rc;
|
enum enum_nested_loop_state rc;
|
||||||
if (not_exists_optimize)
|
|
||||||
return NESTED_LOOP_NO_MORE_ROWS;
|
|
||||||
/* A match from join_tab is found for the current partial join. */
|
/* A match from join_tab is found for the current partial join. */
|
||||||
rc= (*join_tab->next_select)(join, join_tab+1, 0);
|
rc= (*join_tab->next_select)(join, join_tab+1, 0);
|
||||||
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
|
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
|
||||||
|
|
|
@ -434,6 +434,7 @@ public:
|
||||||
void cleanup(bool full);
|
void cleanup(bool full);
|
||||||
void clear();
|
void clear();
|
||||||
bool save_join_tab();
|
bool save_join_tab();
|
||||||
|
bool init_save_join_tab();
|
||||||
bool send_row_on_empty_set()
|
bool send_row_on_empty_set()
|
||||||
{
|
{
|
||||||
return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
|
return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
|
||||||
|
|
Loading…
Add table
Reference in a new issue