Merge bk@192.168.21.1:mysql-5.0

into  mysql.com:/d2/hf/mrg/mysql-5.0-opt
parents c9068232 835189cb
...@@ -352,3 +352,13 @@ select c1 mod 50 as result from t1; ...@@ -352,3 +352,13 @@ select c1 mod 50 as result from t1;
result result
6 6
drop table t1; drop table t1;
select cast(19999999999999999999 as signed);
cast(19999999999999999999 as signed)
9223372036854775807
Warnings:
Error 1292 Truncated incorrect DECIMAL value: ''
select cast(-19999999999999999999 as signed);
cast(-19999999999999999999 as signed)
-9223372036854775808
Warnings:
Error 1292 Truncated incorrect DECIMAL value: ''
...@@ -737,4 +737,30 @@ SELECT GROUP_CONCAT(DISTINCT UCASE(b)) FROM t1; ...@@ -737,4 +737,30 @@ SELECT GROUP_CONCAT(DISTINCT UCASE(b)) FROM t1;
GROUP_CONCAT(DISTINCT UCASE(b)) GROUP_CONCAT(DISTINCT UCASE(b))
ONE.1,TWO.2,ONE.3 ONE.1,TWO.2,ONE.3
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1( a VARCHAR( 10 ), b INT );
INSERT INTO t1 VALUES ( repeat( 'a', 10 ), 1),
( repeat( 'b', 10 ), 2);
SET group_concat_max_len = 20;
SELECT GROUP_CONCAT( a ) FROM t1;
GROUP_CONCAT( a )
aaaaaaaaaa,bbbbbbbbb
Warnings:
Warning 1260 1 line(s) were cut by GROUP_CONCAT()
SELECT GROUP_CONCAT( DISTINCT a ) FROM t1;
GROUP_CONCAT( DISTINCT a )
aaaaaaaaaa,bbbbbbbbb
Warnings:
Warning 1260 1 line(s) were cut by GROUP_CONCAT()
SELECT GROUP_CONCAT( a ORDER BY b ) FROM t1;
GROUP_CONCAT( a ORDER BY b )
aaaaaaaaaa,bbbbbbbbb
Warnings:
Warning 1260 1 line(s) were cut by GROUP_CONCAT()
SELECT GROUP_CONCAT( DISTINCT a ORDER BY b ) FROM t1;
GROUP_CONCAT( DISTINCT a ORDER BY b )
aaaaaaaaaa,bbbbbbbbb
Warnings:
Warning 1260 1 line(s) were cut by GROUP_CONCAT()
SET group_concat_max_len = DEFAULT;
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
...@@ -1330,4 +1330,51 @@ SELECT a,AVG(DISTINCT b) AS average FROM t1 GROUP BY a HAVING average > 50; ...@@ -1330,4 +1330,51 @@ SELECT a,AVG(DISTINCT b) AS average FROM t1 GROUP BY a HAVING average > 50;
a average a average
1 32768.5000 1 32768.5000
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 ( a INT, b INT, KEY(a) );
INSERT INTO t1 VALUES (NULL, 1), (NULL, 2);
EXPLAIN SELECT MIN(a), MIN(b) FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
SELECT MIN(a), MIN(b) FROM t1;
MIN(a) MIN(b)
NULL 1
CREATE TABLE t2( a INT, b INT, c INT, KEY(a, b) );
INSERT INTO t2 ( a, b, c ) VALUES ( 1, NULL, 2 ), ( 1, 3, 4 ), ( 1, 4, 4 );
EXPLAIN SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref a a 5 const 2 Using where
SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1;
MIN(b) MIN(c)
3 2
CREATE TABLE t3 (a INT, b INT, c int, KEY(a, b));
INSERT INTO t3 VALUES (1, NULL, 1), (2, NULL, 2), (2, NULL, 2), (3, NULL, 3);
EXPLAIN SELECT MIN(a), MIN(b) FROM t3 where a = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
SELECT MIN(a), MIN(b) FROM t3 where a = 2;
MIN(a) MIN(b)
2 NULL
CREATE TABLE t4 (a INT, b INT, c int, KEY(a, b));
INSERT INTO t4 VALUES (1, 1, 1), (2, NULL, 2), (2, NULL, 2), (3, 1, 3);
EXPLAIN SELECT MIN(a), MIN(b) FROM t4 where a = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
SELECT MIN(a), MIN(b) FROM t4 where a = 2;
MIN(a) MIN(b)
2 NULL
SELECT MIN(b), min(c) FROM t4 where a = 2;
MIN(b) min(c)
NULL 2
CREATE TABLE t5( a INT, b INT, KEY( a, b) );
INSERT INTO t5 VALUES( 1, 1 ), ( 1, 2 );
EXPLAIN SELECT MIN(a), MIN(b) FROM t5 WHERE a = 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
SELECT MIN(a), MIN(b) FROM t5 WHERE a = 1;
MIN(a) MIN(b)
1 1
SELECT MIN(a), MIN(b) FROM t5 WHERE a = 1 and b > 1;
MIN(a) MIN(b)
1 2
DROP TABLE t1, t2, t3, t4, t5;
End of 5.0 tests End of 5.0 tests
...@@ -144,6 +144,27 @@ SELECT * FROM t1; ...@@ -144,6 +144,27 @@ SELECT * FROM t1;
c1 cnt c1 cnt
1a 2 1a 2
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (
a1 decimal(10,0) DEFAULT NULL,
a2 blob,
a3 time DEFAULT NULL,
a4 blob,
a5 char(175) DEFAULT NULL,
a6 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
a7 tinyblob,
INDEX idx (a6,a7(239),a5)
) ENGINE=InnoDB;
EXPLAIN SELECT a4 FROM t1 WHERE
a6=NULL AND
a4='UNcT5pIde4I6c2SheTo4gt92OV1jgJCVkXmzyf325R1DwLURkbYHwhydANIZMbKTgdcR5xS';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT t1.a4 FROM t1, t1 t WHERE
t.a6=t.a6 AND t1.a6=NULL AND
t1.a4='UNcT5pIde4I6c2SheTo4gt92OV1jgJCVkXmzyf325R1DwLURkbYHwhydANIZMbKTgdcR5xS';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
DROP TABLE t1;
End of 4.1 tests End of 4.1 tests
create table t1m (a int) engine=myisam; create table t1m (a int) engine=myisam;
create table t1i (a int) engine=innodb; create table t1i (a int) engine=innodb;
......
...@@ -1114,6 +1114,28 @@ execute stmt; ...@@ -1114,6 +1114,28 @@ execute stmt;
show create table t1; show create table t1;
drop table t1; drop table t1;
deallocate prepare stmt; deallocate prepare stmt;
CREATE TABLE t1(a int);
INSERT INTO t1 VALUES (2), (3), (1);
PREPARE st1 FROM
'(SELECT a FROM t1) UNION (SELECT a+10 FROM t1) ORDER BY RAND()*0+a';
EXECUTE st1;
a
1
2
3
11
12
13
EXECUTE st1;
a
1
2
3
11
12
13
DEALLOCATE PREPARE st1;
DROP TABLE t1;
End of 4.1 tests. End of 4.1 tests.
create table t1 (a varchar(20)); create table t1 (a varchar(20));
insert into t1 values ('foo'); insert into t1 values ('foo');
......
...@@ -4041,4 +4041,34 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -4041,4 +4041,34 @@ 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 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 2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
INSERT INTO t1 VALUES
(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
INSERT INTO t2 VALUES (7), (5), (1), (3);
SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
id st
3 FL
1 GA
7 FL
SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
GROUP BY id;
id st
1 GA
3 FL
7 FL
SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
id st
2 GA
4 FL
SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
GROUP BY id;
id st
2 GA
4 FL
DROP TABLE t1,t2;
End of 5.0 tests. End of 5.0 tests.
...@@ -346,3 +346,33 @@ call test27759(); ...@@ -346,3 +346,33 @@ call test27759();
a b a_then_b b_then_a c_then_a 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 2007-04-10 2007-04-11 2007-04-10 2007-04-10 2004-04-09 00:00:00
drop procedure test27759; drop procedure test27759;
create table t1 (f1 date);
insert into t1 values (curdate());
select left(f1,10) = curdate() from t1;
left(f1,10) = curdate()
1
drop table t1;
create table t1(f1 date);
insert into t1 values('01-01-01'),('02-02-02'),('01-01-01'),('02-02-02');
set @bug28261='';
select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
if(@bug28261 = f1, '', @bug28261:= f1)
2001-01-01
2002-02-02
2001-01-01
2002-02-02
Warnings:
Warning 1292 Incorrect date value: '' for column 'f1' at row 1
select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
if(@bug28261 = f1, '', @bug28261:= f1)
2001-01-01
2002-02-02
2001-01-01
2002-02-02
select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
if(@bug28261 = f1, '', @bug28261:= f1)
2001-01-01
2002-02-02
2001-01-01
2002-02-02
drop table t1;
...@@ -288,3 +288,9 @@ insert into t1 values (10000002383263201056); ...@@ -288,3 +288,9 @@ insert into t1 values (10000002383263201056);
select c1 mod 50 as result from t1; select c1 mod 50 as result from t1;
drop table t1; drop table t1;
#
# Bug #8663 cant use bgint unsigned as input to cast
#
select cast(19999999999999999999 as signed);
select cast(-19999999999999999999 as signed);
...@@ -507,4 +507,18 @@ SELECT GROUP_CONCAT(DISTINCT UCASE(a)) FROM t1; ...@@ -507,4 +507,18 @@ SELECT GROUP_CONCAT(DISTINCT UCASE(a)) FROM t1;
SELECT GROUP_CONCAT(DISTINCT UCASE(b)) FROM t1; SELECT GROUP_CONCAT(DISTINCT UCASE(b)) FROM t1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #28273: GROUP_CONCAT and ORDER BY: No warning when result gets truncated.
#
CREATE TABLE t1( a VARCHAR( 10 ), b INT );
INSERT INTO t1 VALUES ( repeat( 'a', 10 ), 1),
( repeat( 'b', 10 ), 2);
SET group_concat_max_len = 20;
SELECT GROUP_CONCAT( a ) FROM t1;
SELECT GROUP_CONCAT( DISTINCT a ) FROM t1;
SELECT GROUP_CONCAT( a ORDER BY b ) FROM t1;
SELECT GROUP_CONCAT( DISTINCT a ORDER BY b ) FROM t1;
SET group_concat_max_len = DEFAULT;
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -827,4 +827,38 @@ SELECT a,AVG(DISTINCT b) AS average FROM t1 GROUP BY a HAVING average > 50; ...@@ -827,4 +827,38 @@ SELECT a,AVG(DISTINCT b) AS average FROM t1 GROUP BY a HAVING average > 50;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #27573: MIN() on an indexed column which is always NULL sets _other_
# results to NULL
#
CREATE TABLE t1 ( a INT, b INT, KEY(a) );
INSERT INTO t1 VALUES (NULL, 1), (NULL, 2);
EXPLAIN SELECT MIN(a), MIN(b) FROM t1;
SELECT MIN(a), MIN(b) FROM t1;
CREATE TABLE t2( a INT, b INT, c INT, KEY(a, b) );
INSERT INTO t2 ( a, b, c ) VALUES ( 1, NULL, 2 ), ( 1, 3, 4 ), ( 1, 4, 4 );
EXPLAIN SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1;
SELECT MIN(b), MIN(c) FROM t2 WHERE a = 1;
CREATE TABLE t3 (a INT, b INT, c int, KEY(a, b));
INSERT INTO t3 VALUES (1, NULL, 1), (2, NULL, 2), (2, NULL, 2), (3, NULL, 3);
EXPLAIN SELECT MIN(a), MIN(b) FROM t3 where a = 2;
SELECT MIN(a), MIN(b) FROM t3 where a = 2;
CREATE TABLE t4 (a INT, b INT, c int, KEY(a, b));
INSERT INTO t4 VALUES (1, 1, 1), (2, NULL, 2), (2, NULL, 2), (3, 1, 3);
EXPLAIN SELECT MIN(a), MIN(b) FROM t4 where a = 2;
SELECT MIN(a), MIN(b) FROM t4 where a = 2;
SELECT MIN(b), min(c) FROM t4 where a = 2;
CREATE TABLE t5( a INT, b INT, KEY( a, b) );
INSERT INTO t5 VALUES( 1, 1 ), ( 1, 2 );
EXPLAIN SELECT MIN(a), MIN(b) FROM t5 WHERE a = 1;
SELECT MIN(a), MIN(b) FROM t5 WHERE a = 1;
SELECT MIN(a), MIN(b) FROM t5 WHERE a = 1 and b > 1;
DROP TABLE t1, t2, t3, t4, t5;
###
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -169,6 +169,31 @@ INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1; ...@@ -169,6 +169,31 @@ INSERT INTO t1 (c1) VALUES ('1b') ON DUPLICATE KEY UPDATE cnt=cnt+1;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #28272: EXPLAIN for SELECT from an empty InnoDB table
#
CREATE TABLE t1 (
a1 decimal(10,0) DEFAULT NULL,
a2 blob,
a3 time DEFAULT NULL,
a4 blob,
a5 char(175) DEFAULT NULL,
a6 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
a7 tinyblob,
INDEX idx (a6,a7(239),a5)
) ENGINE=InnoDB;
EXPLAIN SELECT a4 FROM t1 WHERE
a6=NULL AND
a4='UNcT5pIde4I6c2SheTo4gt92OV1jgJCVkXmzyf325R1DwLURkbYHwhydANIZMbKTgdcR5xS';
EXPLAIN SELECT t1.a4 FROM t1, t1 t WHERE
t.a6=t.a6 AND t1.a6=NULL AND
t1.a4='UNcT5pIde4I6c2SheTo4gt92OV1jgJCVkXmzyf325R1DwLURkbYHwhydANIZMbKTgdcR5xS';
DROP TABLE t1;
--echo End of 4.1 tests --echo End of 4.1 tests
# #
# Bug #12882 min/max inconsistent on empty table # Bug #12882 min/max inconsistent on empty table
......
...@@ -1194,6 +1194,24 @@ show create table t1; ...@@ -1194,6 +1194,24 @@ show create table t1;
--enable_warnings --enable_warnings
drop table t1; drop table t1;
deallocate prepare stmt; deallocate prepare stmt;
#
#
# Bug #27937: crash on the second execution for prepared statement
# from UNION with ORDER BY an expression containing RAND()
#
CREATE TABLE t1(a int);
INSERT INTO t1 VALUES (2), (3), (1);
PREPARE st1 FROM
'(SELECT a FROM t1) UNION (SELECT a+10 FROM t1) ORDER BY RAND()*0+a';
EXECUTE st1;
EXECUTE st1;
DEALLOCATE PREPARE st1;
DROP TABLE t1;
--echo End of 4.1 tests. --echo End of 4.1 tests.
......
...@@ -2882,4 +2882,28 @@ INSERT INTO t1 VALUES (1,1),(2,1); ...@@ -2882,4 +2882,28 @@ INSERT INTO t1 VALUES (1,1),(2,1);
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b); EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
DROP TABLE t1; DROP TABLE t1;
#
# Bug #28377: grouping query with a correlated subquery in WHERE condition
#
CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
INSERT INTO t1 VALUES
(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
INSERT INTO t2 VALUES (7), (5), (1), (3);
SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
GROUP BY id;
SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
GROUP BY id;
DROP TABLE t1,t2;
--echo End of 5.0 tests. --echo End of 5.0 tests.
...@@ -225,3 +225,24 @@ END;| ...@@ -225,3 +225,24 @@ END;|
DELIMITER ;| DELIMITER ;|
call test27759(); call test27759();
drop procedure test27759; drop procedure test27759;
#
# Bug#28208: Wrong result of a non-const STRING function with a const
# DATETIME function.
#
create table t1 (f1 date);
insert into t1 values (curdate());
select left(f1,10) = curdate() from t1;
drop table t1;
#
# Bug#28261: Wrong DATETIME comparison result when the GET_USER_VAR function
# is involved.
#
create table t1(f1 date);
insert into t1 values('01-01-01'),('02-02-02'),('01-01-01'),('02-02-02');
set @bug28261='';
select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
select if(@bug28261 = f1, '', @bug28261:= f1) from t1;
drop table t1;
...@@ -3503,7 +3503,8 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) ...@@ -3503,7 +3503,8 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
prev_subselect_item->const_item_cache= 0; prev_subselect_item->const_item_cache= 0;
set_field(*from_field); set_field(*from_field);
if (!last_checked_context->select_lex->having_fix_field && if (!last_checked_context->select_lex->having_fix_field &&
select->group_list.elements) select->group_list.elements &&
(place == SELECT_LIST || place == IN_HAVING))
{ {
Item_outer_ref *rf; Item_outer_ref *rf;
/* /*
......
...@@ -633,7 +633,13 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value) ...@@ -633,7 +633,13 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value)
if (cmp_type != CMP_DATE_DFLT) if (cmp_type != CMP_DATE_DFLT)
{ {
if (cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item()) /*
Do not cache GET_USER_VAR() function as its const_item() may return TRUE
for the current thread but it still may change during the execution.
*/
if (cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() &&
(str_arg->type() != Item::FUNC_ITEM ||
((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC))
{ {
THD *thd= current_thd; THD *thd= current_thd;
ulonglong value; ulonglong value;
...@@ -661,7 +667,7 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, ...@@ -661,7 +667,7 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
Item_result type) Item_result type)
{ {
enum enum_date_cmp_type cmp_type; enum enum_date_cmp_type cmp_type;
ulonglong const_value; ulonglong const_value= (ulonglong)-1;
a= a1; a= a1;
b= a2; b= a2;
...@@ -674,8 +680,7 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, ...@@ -674,8 +680,7 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
a_cache= 0; a_cache= 0;
b_cache= 0; b_cache= 0;
if (cmp_type != CMP_DATE_WITH_DATE && if (const_value != (ulonglong)-1)
((*b)->const_item() || (*a)->const_item()))
{ {
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. */
...@@ -781,7 +786,12 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, ...@@ -781,7 +786,12 @@ 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() && cache_arg) /*
Do not cache GET_USER_VAR() function as its const_item() may return TRUE
for the current thread but it still may change during the execution.
*/
if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM ||
((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC))
{ {
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. */
......
...@@ -3339,6 +3339,10 @@ String* Item_func_group_concat::val_str(String* str) ...@@ -3339,6 +3339,10 @@ String* Item_func_group_concat::val_str(String* str)
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (null_value) if (null_value)
return 0; return 0;
if (!result.length() && tree)
/* Tree is used for sorting as in ORDER BY */
tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
left_root_right);
if (count_cut_values && !warning) if (count_cut_values && !warning)
{ {
/* /*
...@@ -3350,11 +3354,6 @@ String* Item_func_group_concat::val_str(String* str) ...@@ -3350,11 +3354,6 @@ String* Item_func_group_concat::val_str(String* str)
ER_CUT_VALUE_GROUP_CONCAT, ER_CUT_VALUE_GROUP_CONCAT,
ER(ER_CUT_VALUE_GROUP_CONCAT)); ER(ER_CUT_VALUE_GROUP_CONCAT));
} }
if (result.length())
return &result;
if (tree)
tree_walk(tree, (tree_walk_action)&dump_leaf_key, (void*)this,
left_root_right);
return &result; return &result;
} }
......
...@@ -206,12 +206,68 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) ...@@ -206,12 +206,68 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
if (!ref.key_length) if (!ref.key_length)
error= table->file->index_first(table->record[0]); error= table->file->index_first(table->record[0]);
else else
error= table->file->index_read(table->record[0],key_buff, {
ref.key_length, /*
range_fl & NEAR_MIN ? Use index to replace MIN/MAX functions with their values
HA_READ_AFTER_KEY : according to the following rules:
HA_READ_KEY_OR_NEXT);
1) Insert the minimum non-null values where the WHERE clause still
matches, or
2) a NULL value if there are only NULL values for key_part_k.
3) Fail, producing a row of nulls
Implementation: Read the smallest value using the search key. If
the interval is open, read the next value after the search
key. If read fails, and we're looking for a MIN() value for a
nullable column, test if there is an exact match for the key.
*/
if (!(range_fl & NEAR_MIN))
/*
Closed interval: Either The MIN argument is non-nullable, or
we have a >= predicate for the MIN argument.
*/
error= table->file->index_read(table->record[0], ref.key_buff,
ref.key_length,
HA_READ_KEY_OR_NEXT);
else
{
/*
Open interval: There are two cases:
1) We have only MIN() and the argument column is nullable, or
2) there is a > predicate on it, nullability is irrelevant.
We need to scan the next bigger record first.
*/
error= table->file->index_read(table->record[0], ref.key_buff,
ref.key_length, HA_READ_AFTER_KEY);
/*
If the found record is outside the group formed by the search
prefix, or there is no such record at all, check if all
records in that group have NULL in the MIN argument
column. If that is the case return that NULL.
Check if case 1 from above holds. If it does, we should read
the skipped tuple.
*/
if (ref.key_buff[prefix_len] == 1 &&
/*
Last keypart (i.e. the argument to MIN) is set to NULL by
find_key_for_maxmin only if all other keyparts are bound
to constants in a conjunction of equalities. Hence, we
can detect this by checking only if the last keypart is
NULL.
*/
(error == HA_ERR_KEY_NOT_FOUND ||
key_cmp_if_same(table, ref.key_buff, ref.key, prefix_len)))
{
DBUG_ASSERT(item_field->field->real_maybe_null());
error= table->file->index_read(table->record[0], ref.key_buff,
ref.key_length,
HA_READ_KEY_EXACT);
}
}
}
/* Verify that the read tuple indeed matches the search key */
if (!error && reckey_in_range(0, &ref, item_field->field, if (!error && reckey_in_range(0, &ref, item_field->field,
conds, range_fl, prefix_len)) conds, range_fl, prefix_len))
error= HA_ERR_KEY_NOT_FOUND; error= HA_ERR_KEY_NOT_FOUND;
...@@ -739,14 +795,24 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, ...@@ -739,14 +795,24 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
if (!max_fl && key_part_used == key_part_to_use && part->null_bit) if (!max_fl && key_part_used == key_part_to_use && part->null_bit)
{ {
/* /*
SELECT MIN(key_part2) FROM t1 WHERE key_part1=const The query is on this form:
If key_part2 may be NULL, then we want to find the first row
that is not null SELECT MIN(key_part_k)
FROM t1
WHERE key_part_1 = const and ... and key_part_k-1 = const
If key_part_k is nullable, we want to find the first matching row
where key_part_k is not null. The key buffer is now {const, ...,
NULL}. This will be passed to the handler along with a flag
indicating open interval. If a tuple is read that does not match
these search criteria, an attempt will be made to read an exact
match for the key buffer.
*/ */
/* Set the first byte of key_part_k to 1, that means NULL */
ref->key_buff[ref->key_length]= 1; ref->key_buff[ref->key_length]= 1;
ref->key_length+= part->store_length; ref->key_length+= part->store_length;
*range_fl&= ~NO_MIN_RANGE; *range_fl&= ~NO_MIN_RANGE;
*range_fl|= NEAR_MIN; // > NULL *range_fl|= NEAR_MIN; // Open interval
} }
/* /*
The following test is false when the key in the key tree is The following test is false when the key in the key tree is
......
...@@ -976,6 +976,12 @@ JOIN::optimize() ...@@ -976,6 +976,12 @@ JOIN::optimize()
} }
} }
if (conds &&!outer_join && const_table_map != found_const_table_map &&
(select_options & SELECT_DESCRIBE) &&
select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
{
conds=new Item_int((longlong) 0,1); // Always false
}
if (make_join_select(this, select, conds)) if (make_join_select(this, select, conds))
{ {
zero_result_cause= zero_result_cause=
......
...@@ -147,8 +147,16 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) ...@@ -147,8 +147,16 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
fake_select_lex->table_list.link_in_list((byte *)&result_table_list, fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
(byte **) (byte **)
&result_table_list.next_local); &result_table_list.next_local);
fake_select_lex->context.table_list= fake_select_lex->context.first_name_resolution_table= fake_select_lex->context.table_list=
fake_select_lex->context.first_name_resolution_table=
fake_select_lex->get_table_list(); fake_select_lex->get_table_list();
if (!fake_select_lex->first_execution)
{
for (ORDER *order= (ORDER *) global_parameters->order_list.first;
order;
order= order->next)
order->item= &order->item_ptr;
}
for (ORDER *order= (ORDER *)global_parameters->order_list.first; for (ORDER *order= (ORDER *)global_parameters->order_list.first;
order; order;
order=order->next) order=order->next)
......
...@@ -1083,7 +1083,11 @@ int decimal2longlong(decimal_t *from, longlong *to) ...@@ -1083,7 +1083,11 @@ int decimal2longlong(decimal_t *from, longlong *to)
x=x*DIG_BASE - *buf++; x=x*DIG_BASE - *buf++;
if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y)) if (unlikely(y < (LONGLONG_MIN/DIG_BASE) || x > y))
{ {
*to= from->sign ? y : -y; /*
the decimal is bigger than any possible integer
return border integer depending on the sign
*/
*to= from->sign ? LONGLONG_MIN : LONGLONG_MAX;
return E_DEC_OVERFLOW; return E_DEC_OVERFLOW;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment