Merge kaamos.(none):/data/src/mysql-5.0

into  kaamos.(none):/data/src/opt/mysql-5.0-opt
This commit is contained in:
kaa@kaamos.(none) 2008-01-10 20:43:05 +03:00
commit f8ade5e91b
41 changed files with 755 additions and 163 deletions

View file

@ -3083,7 +3083,10 @@ com_connect(String *buffer, char *line)
Two null bytes are needed in the end of buff to allow
get_arg to find end of string the second time it's called.
*/
strmake(buff, line, sizeof(buff)-2);
tmp= strmake(buff, line, sizeof(buff)-2);
#ifdef EXTRA_DEBUG
tmp[1]= 0;
#endif
tmp= get_arg(buff, 0);
if (tmp && *tmp)
{

View file

@ -3592,7 +3592,7 @@ void do_get_file_name(struct st_command *command,
if (*p)
*p++= 0;
command->last_argument= p;
strmake(dest, name, dest_max_len);
strmake(dest, name, dest_max_len - 1);
}
@ -6908,7 +6908,7 @@ int main(int argc, char **argv)
if (save_file[0])
{
strmake(command->require_file, save_file, sizeof(save_file));
strmake(command->require_file, save_file, sizeof(save_file) - 1);
save_file[0]= 0;
}
run_query(cur_con, command, flags);

View file

@ -271,7 +271,7 @@ group_concat(distinct s1 order by s2)
c,b,a
select group_concat(distinct s1 order by s2) from t1;
group_concat(distinct s1 order by s2)
c,b,a,c
c,b,a
drop table t1;
create table t1 (a int, c int);
insert into t1 values (1, 2), (2, 3), (2, 4), (3, 5);
@ -870,4 +870,65 @@ select group_concat(f1) from t1;
group_concat(f1)
,
drop table t1;
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1, 1), (2, 2), (2, 3);
SELECT GROUP_CONCAT(DISTINCT a ORDER BY b) FROM t1;
GROUP_CONCAT(DISTINCT a ORDER BY b)
1,2
SELECT GROUP_CONCAT(DISTINCT a ORDER BY b DESC) FROM t1;
GROUP_CONCAT(DISTINCT a ORDER BY b DESC)
2,1
SELECT GROUP_CONCAT(DISTINCT a) FROM t1;
GROUP_CONCAT(DISTINCT a)
1,2
SELECT GROUP_CONCAT(DISTINCT a + 1 ORDER BY 3 - b) FROM t1;
GROUP_CONCAT(DISTINCT a + 1 ORDER BY 3 - b)
3,2
SELECT GROUP_CONCAT(DISTINCT a + 1 ORDER BY b) FROM t1;
GROUP_CONCAT(DISTINCT a + 1 ORDER BY b)
2,3
SELECT GROUP_CONCAT(a ORDER BY 3 - b) FROM t1;
GROUP_CONCAT(a ORDER BY 3 - b)
2,2,1
CREATE TABLE t2 (a INT, b INT, c INT, d INT);
INSERT INTO t2 VALUES (1,1, 1,1), (1,1, 2,2), (1,2, 2,1), (2,1, 1,2);
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY c, d) FROM t2;
GROUP_CONCAT(DISTINCT a, b ORDER BY c, d)
11,21,12
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY d, c) FROM t2;
GROUP_CONCAT(DISTINCT a, b ORDER BY d, c)
11,12,21
CREATE TABLE t3 (a INT, b INT, c INT);
INSERT INTO t3 VALUES (1, 1, 1), (2, 1, 2), (3, 2, 1);
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY b, c) FROM t3;
GROUP_CONCAT(DISTINCT a, b ORDER BY b, c)
11,21,32
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY c, b) FROM t3;
GROUP_CONCAT(DISTINCT a, b ORDER BY c, b)
11,32,21
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY a, b) FROM t1;
GROUP_CONCAT(DISTINCT a, b ORDER BY a, b)
11,22,23
SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) FROM t1;
GROUP_CONCAT(DISTINCT b, a ORDER BY a, b)
11,22,32
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY b, a) FROM t1;
GROUP_CONCAT(DISTINCT a, b ORDER BY b, a)
11,22,23
SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) FROM t1;
GROUP_CONCAT(DISTINCT b, a ORDER BY a, b)
11,22,32
SELECT GROUP_CONCAT(DISTINCT a ORDER BY a, b) FROM t1;
GROUP_CONCAT(DISTINCT a ORDER BY a, b)
1,2
SELECT GROUP_CONCAT(DISTINCT b ORDER BY b, a) FROM t1;
GROUP_CONCAT(DISTINCT b ORDER BY b, a)
1,2,3
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY a) FROM t1;
GROUP_CONCAT(DISTINCT a, b ORDER BY a)
11,23,22
SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY b) FROM t1;
GROUP_CONCAT(DISTINCT b, a ORDER BY b)
11,22,32
DROP TABLE t1, t2, t3;
End of 5.0 tests

View file

@ -1407,4 +1407,16 @@ SELECT COUNT(*), a FROM t1;
COUNT(*) a
4 1
DROP TABLE t1;
set SQL_MODE=ONLY_FULL_GROUP_BY;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3),(4);
CREATE VIEW v1 AS SELECT a,(a + 1) AS y FROM t1;
EXPLAIN EXTENDED SELECT y FROM v1 GROUP BY v1.y;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
Warnings:
Note 1003 select (`test`.`t1`.`a` + 1) AS `y` from `test`.`t1` group by (`test`.`t1`.`a` + 1)
DROP VIEW v1;
DROP TABLE t1;
SET SQL_MODE=DEFAULT;
End of 5.0 tests

View file

@ -1282,4 +1282,7 @@ DATE_ADD('20071108', INTERVAL 1 DAY)
select DATE_ADD(20071108, INTERVAL 1 DAY);
DATE_ADD(20071108, INTERVAL 1 DAY)
2007-11-09
select LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND;
LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND
2007-12-30 23:59:59
End of 5.0 tests

View file

@ -88,21 +88,25 @@ select a=b && a=c from t1;
a=b && a=c
1
SELECT routine_name, definer
FROM information_schema.routines;
FROM information_schema.routines
WHERE routine_name = 'bug12480';
routine_name definer
bug12480 root@localhost
SELECT trigger_name, definer
FROM information_schema.triggers;
FROM information_schema.triggers
WHERE trigger_name = 't1_first';
trigger_name definer
t1_first root@localhost
--- On slave --
SELECT routine_name, definer
FROM information_schema.routines;
FROM information_schema.routines
WHERE routine_name = 'bug12480';
routine_name definer
bug12480 root@localhost
SELECT trigger_name, definer
FROM information_schema.triggers;
FROM information_schema.triggers
WHERE trigger_name = 't1_first';
trigger_name definer
t1_first root@localhost
select a=b && a=c from t1;

View file

@ -70,8 +70,4 @@ count(*)
select count(*) from information_schema.USER_PRIVILEGES;
count(*)
0
CREATE FUNCTION a RETURNS STRING SONAME '';
ERROR HY000: Can't initialize function 'a'; UDFs are unavailable with the --skip-grant-tables option
DROP FUNCTION a;
ERROR 42000: FUNCTION test.a does not exist
End of 5.0 tests

View file

@ -4383,4 +4383,13 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a))' at line 2
DROP TABLE t1,t2;
create table t1(f11 int, f12 int);
create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
insert into t1 values(1,1),(2,2), (3, 3);
set session sort_buffer_size= 33*1024;
select count(*) from t1 where f12 =
(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
count(*)
3
drop table t1,t2;
End of 5.0 tests.

View file

@ -251,4 +251,9 @@ INSERT INTO t1 VALUES ('1000-00-00');
ERROR 22007: Incorrect date value: '1000-00-00' for column 'a' at row 1
SET SQL_MODE=DEFAULT;
DROP TABLE t1,t2;
CREATE TABLE t1 SELECT curdate() AS f1;
SELECT hour(f1), minute(f1), second(f1) FROM t1;
hour(f1) minute(f1) second(f1)
0 0 0
DROP TABLE t1;
End of 5.0 tests

View file

@ -786,10 +786,6 @@ from (select 1 as s,'t' as t union select null, null ) as sub1;
select group_concat(t) from t1 group by week(date)/10;
group_concat(t)
t
Warnings:
Warning 1292 Truncated incorrect datetime value: '0000-00-00'
Warning 1292 Truncated incorrect datetime value: '0000-00-00'
Warning 1292 Truncated incorrect datetime value: '0000-00-00'
drop table t1;
CREATE TABLE t1 (
qty decimal(16,6) default NULL,

View file

@ -0,0 +1,5 @@
CREATE FUNCTION a RETURNS STRING SONAME '';
ERROR HY000: Can't initialize function 'a'; UDFs are unavailable with the --skip-grant-tables option
DROP FUNCTION a;
ERROR 42000: FUNCTION test.a does not exist
End of 5.0 tests

View file

@ -1389,4 +1389,121 @@ select @var;
1
(select 2) union (select 1 into @var);
ERROR 42000: Result consisted of more than one row
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (10), (20);
CREATE TABLE t2 (b int);
INSERT INTO t2 VALUES (10), (50), (50);
SELECT a,1 FROM t1
UNION
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP
ORDER BY a;
a 1
NULL 3
10 1
20 1
50 2
SELECT a,1 FROM t1
UNION
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP
ORDER BY a DESC;
a 1
50 2
20 1
10 1
NULL 3
SELECT a,1 FROM t1
UNION
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP
ORDER BY a ASC LIMIT 3;
a 1
NULL 3
10 1
20 1
SELECT a,1 FROM t1
UNION ALL
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP
ORDER BY a DESC;
a 1
50 2
20 1
10 1
10 1
NULL 3
SELECT a,1 FROM t1
UNION
(SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a);
ERROR HY000: Incorrect usage of CUBE/ROLLUP and ORDER BY
SELECT a,1 FROM t1
UNION ALL
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a
UNION
SELECT 1,1;
ERROR HY000: Incorrect usage of UNION and ORDER BY
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
SELECT a INTO @v FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1
) alias;
SELECT a INTO OUTFILE 'union.out.file' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
SELECT a INTO DUMPFILE 'union.out.file2' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO @v FROM t1
) alias;
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO OUTFILE 'union.out.file3' FROM t1
) alias;
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO DUMPFILE 'union.out.file4' FROM t1
) alias;
SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1;
SELECT a INTO @v FROM t1 UNION SELECT a FROM t1;
ERROR HY000: Incorrect usage of UNION and INTO
SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1;
ERROR HY000: Incorrect usage of UNION and INTO
SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1;
ERROR HY000: Incorrect usage of UNION and INTO
DROP TABLE t1;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1), (2), (3);
CREATE TABLE t2 SELECT * FROM (SELECT NULL) a UNION SELECT a FROM t1;
DESC t2;
Field Type Null Key Default Extra
NULL int(11) YES NULL
CREATE TABLE t3 SELECT a FROM t1 UNION SELECT * FROM (SELECT NULL) a;
DESC t3;
Field Type Null Key Default Extra
a int(11) YES NULL
CREATE TABLE t4 SELECT NULL;
DESC t4;
Field Type Null Key Default Extra
NULL binary(0) YES NULL
CREATE TABLE t5 SELECT NULL UNION SELECT NULL;
DESC t5;
Field Type Null Key Default Extra
NULL binary(0) YES NULL
CREATE TABLE t6
SELECT * FROM (SELECT * FROM (SELECT NULL)a) b UNION SELECT a FROM t1;
DESC t6;
Field Type Null Key Default Extra
NULL int(11) YES NULL
DROP TABLE t1, t2, t3, t4, t5, t6;
End of 5.0 tests

View file

@ -598,5 +598,46 @@ insert into t1 values (''),('');
select group_concat(distinct f1) from t1;
select group_concat(f1) from t1;
drop table t1;
# Bug#32798: DISTINCT in GROUP_CONCAT clause fails when ordering by a column
# with null values
#'
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1, 1), (2, 2), (2, 3);
SELECT GROUP_CONCAT(DISTINCT a ORDER BY b) FROM t1;
SELECT GROUP_CONCAT(DISTINCT a ORDER BY b DESC) FROM t1;
SELECT GROUP_CONCAT(DISTINCT a) FROM t1;
SELECT GROUP_CONCAT(DISTINCT a + 1 ORDER BY 3 - b) FROM t1;
SELECT GROUP_CONCAT(DISTINCT a + 1 ORDER BY b) FROM t1;
SELECT GROUP_CONCAT(a ORDER BY 3 - b) FROM t1;
CREATE TABLE t2 (a INT, b INT, c INT, d INT);
# There is one duplicate in the expression list: 1,10
# There is one duplicate in ORDER BY list, but that shouldnt matter: 1,10
INSERT INTO t2 VALUES (1,1, 1,1), (1,1, 2,2), (1,2, 2,1), (2,1, 1,2);
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY c, d) FROM t2;
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY d, c) FROM t2;
CREATE TABLE t3 (a INT, b INT, c INT);
INSERT INTO t3 VALUES (1, 1, 1), (2, 1, 2), (3, 2, 1);
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY b, c) FROM t3;
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY c, b) FROM t3;
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY a, b) FROM t1;
SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) FROM t1;
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY b, a) FROM t1;
SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY a, b) FROM t1;
SELECT GROUP_CONCAT(DISTINCT a ORDER BY a, b) FROM t1;
SELECT GROUP_CONCAT(DISTINCT b ORDER BY b, a) FROM t1;
SELECT GROUP_CONCAT(DISTINCT a, b ORDER BY a) FROM t1;
SELECT GROUP_CONCAT(DISTINCT b, a ORDER BY b) FROM t1;
DROP TABLE t1, t2, t3;
--echo End of 5.0 tests

View file

@ -901,5 +901,20 @@ SELECT COUNT(*), a FROM t1;
DROP TABLE t1;
#
# Bug #33133: Views are not transparent
#
set SQL_MODE=ONLY_FULL_GROUP_BY;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3),(4);
CREATE VIEW v1 AS SELECT a,(a + 1) AS y FROM t1;
EXPLAIN EXTENDED SELECT y FROM v1 GROUP BY v1.y;
DROP VIEW v1;
DROP TABLE t1;
SET SQL_MODE=DEFAULT;
###
--echo End of 5.0 tests

View file

@ -797,4 +797,11 @@ select DATE_ADD(20071108181000, INTERVAL 1 DAY);
select DATE_ADD('20071108', INTERVAL 1 DAY);
select DATE_ADD(20071108, INTERVAL 1 DAY);
#
# Bug#32770: LAST_DAY() returns a DATE, but somehow internally keeps
# track of the TIME.
#
select LAST_DAY('2007-12-06 08:59:19.05') - INTERVAL 1 SECOND;
--echo End of 5.0 tests

View file

@ -93,10 +93,12 @@ let $time=`select a from t1`;
# - dump definers on the slave;
SELECT routine_name, definer
FROM information_schema.routines;
FROM information_schema.routines
WHERE routine_name = 'bug12480';
SELECT trigger_name, definer
FROM information_schema.triggers;
FROM information_schema.triggers
WHERE trigger_name = 't1_first';
save_master_pos;
connection slave;
@ -111,10 +113,12 @@ select "--- On slave --" as "";
# item.
SELECT routine_name, definer
FROM information_schema.routines;
FROM information_schema.routines
WHERE routine_name = 'bug12480';
SELECT trigger_name, definer
FROM information_schema.triggers;
FROM information_schema.triggers
WHERE trigger_name = 't1_first';
select a=b && a=c from t1;
--disable_query_log

View file

@ -117,14 +117,4 @@ select count(*) from information_schema.SCHEMA_PRIVILEGES;
select count(*) from information_schema.TABLE_PRIVILEGES;
select count(*) from information_schema.USER_PRIVILEGES;
#
# Bug #32020: loading udfs while --skip-grant-tables is enabled causes out of
# memory errors
#
--error ER_CANT_INITIALIZE_UDF
CREATE FUNCTION a RETURNS STRING SONAME '';
--error ER_SP_DOES_NOT_EXIST
DROP FUNCTION a;
--echo End of 5.0 tests

View file

@ -3230,4 +3230,26 @@ SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
DROP TABLE t1,t2;
#
# Bug#33675: Usage of an uninitialized memory by filesort in a subquery
# caused server crash.
#
create table t1(f11 int, f12 int);
create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
insert into t1 values(1,1),(2,2), (3, 3);
let $i=10000;
--disable_query_log
--disable_warnings
while ($i)
{
eval insert into t2 values (-1 , $i/5000 + 1, '$i');
dec $i;
}
--enable_warnings
--enable_query_log
set session sort_buffer_size= 33*1024;
select count(*) from t1 where f12 =
(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
drop table t1,t2;
--echo End of 5.0 tests.

View file

@ -210,4 +210,12 @@ INSERT INTO t1 VALUES ('1000-00-00');
SET SQL_MODE=DEFAULT;
DROP TABLE t1,t2;
#
# Bug #31990: MINUTE() and SECOND() return bogus results when used on a DATE
#
CREATE TABLE t1 SELECT curdate() AS f1;
SELECT hour(f1), minute(f1), second(f1) FROM t1;
DROP TABLE t1;
--echo End of 5.0 tests

View file

@ -0,0 +1 @@
--skip-grant-tables

View file

@ -0,0 +1,28 @@
####################### udf_skip_grants.test ###########################
# #
# Test for bug #32020 "loading udfs while --skip-grant-tables is #
# enabled causes out of memory errors" #
# #
# Creation: #
# 2007-12-24 akopytov Moved the test case for bug #32020 from #
# skip_grants.test to a separate test to ensure #
# that it is only run when the server is built #
# with support for dynamically loaded libraries #
# (see bug #33305). #
# #
########################################################################
-- source include/not_embedded.inc
-- source include/have_udf.inc
#
# Bug #32020: loading udfs while --skip-grant-tables is enabled causes out of
# memory errors
#
--error ER_CANT_INITIALIZE_UDF
CREATE FUNCTION a RETURNS STRING SONAME '';
--error ER_SP_DOES_NOT_EXIST
DROP FUNCTION a;
--echo End of 5.0 tests

View file

@ -877,4 +877,127 @@ DROP TABLE t1;
select @var;
--error 1172
(select 2) union (select 1 into @var);
#
# Bug#27848: order-by of union clashes with rollup of select part
#
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (10), (20);
CREATE TABLE t2 (b int);
INSERT INTO t2 VALUES (10), (50), (50);
SELECT a,1 FROM t1
UNION
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP
ORDER BY a;
SELECT a,1 FROM t1
UNION
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP
ORDER BY a DESC;
SELECT a,1 FROM t1
UNION
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP
ORDER BY a ASC LIMIT 3;
SELECT a,1 FROM t1
UNION ALL
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP
ORDER BY a DESC;
--error ER_WRONG_USAGE
SELECT a,1 FROM t1
UNION
(SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a);
--error ER_WRONG_USAGE
SELECT a,1 FROM t1
UNION ALL
SELECT b, COUNT(*) FROM t2 GROUP BY b WITH ROLLUP ORDER BY a
UNION
SELECT 1,1;
DROP TABLE t1,t2;
# Bug#32858: Erro: "Incorrect usage of UNION and INTO" does not take subselects
# into account
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
SELECT a INTO @v FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1
) alias;
SELECT a INTO OUTFILE 'union.out.file' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
SELECT a INTO DUMPFILE 'union.out.file2' FROM (
SELECT a FROM t1
UNION
SELECT a FROM t1 WHERE 0
) alias;
#
# INTO will not be allowed in subqueries in version 5.1 and above.
#
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO @v FROM t1
) alias;
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO OUTFILE 'union.out.file3' FROM t1
) alias;
SELECT a FROM (
SELECT a FROM t1
UNION
SELECT a INTO DUMPFILE 'union.out.file4' FROM t1
) alias;
SELECT a FROM t1 UNION SELECT a INTO @v FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file5' FROM t1;
SELECT a FROM t1 UNION SELECT a INTO OUTFILE 'union.out.file6' FROM t1;
--error ER_WRONG_USAGE
SELECT a INTO @v FROM t1 UNION SELECT a FROM t1;
--error ER_WRONG_USAGE
SELECT a INTO OUTFILE 'union.out.file7' FROM t1 UNION SELECT a FROM t1;
--error ER_WRONG_USAGE
SELECT a INTO DUMPFILE 'union.out.file8' FROM t1 UNION SELECT a FROM t1;
DROP TABLE t1;
# Bug#32848: Data type conversion bug in union subselects in MySQL 5.0.38
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1), (2), (3);
CREATE TABLE t2 SELECT * FROM (SELECT NULL) a UNION SELECT a FROM t1;
DESC t2;
CREATE TABLE t3 SELECT a FROM t1 UNION SELECT * FROM (SELECT NULL) a;
DESC t3;
CREATE TABLE t4 SELECT NULL;
DESC t4;
CREATE TABLE t5 SELECT NULL UNION SELECT NULL;
DESC t5;
CREATE TABLE t6
SELECT * FROM (SELECT * FROM (SELECT NULL)a) b UNION SELECT a FROM t1;
DESC t6;
DROP TABLE t1, t2, t3, t4, t5, t6;
--echo End of 5.0 tests

View file

@ -271,7 +271,7 @@ void symdirget(char *dir)
SYNOPSIS
unpack_dirname()
to Store result here. May be = from
to result-buffer, FN_REFLEN characters. may be == from
from 'Packed' directory name (may contain ~)
IMPLEMENTATION
@ -397,7 +397,7 @@ uint unpack_filename(my_string to, const char *from)
/* Convert filename (unix standard) to system standard */
/* Used before system command's like open(), create() .. */
/* Returns length of to */
/* Returns used length of to; total length should be FN_REFLEN */
uint system_filename(my_string to, const char *from)
{

View file

@ -1304,7 +1304,8 @@ Field::Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
field_name(field_name_arg),
query_id(0), key_start(0), part_of_key(0), part_of_sortkey(0),
unireg_check(unireg_check_arg),
field_length(length_arg), null_bit(null_bit_arg)
field_length(length_arg), null_bit(null_bit_arg),
is_created_from_null_item(FALSE)
{
flags=null_ptr ? 0: NOT_NULL_FLAG;
comment.str= (char*) "";
@ -5194,6 +5195,13 @@ String *Field_date::val_str(String *val_buffer,
}
bool Field_date::get_time(MYSQL_TIME *ltime)
{
bzero((char *)ltime, sizeof(MYSQL_TIME));
return 0;
}
int Field_date::cmp(const char *a_ptr, const char *b_ptr)
{
int32 a,b;

View file

@ -89,6 +89,16 @@ public:
uint field_index; // field number in fields array
uint16 flags;
uchar null_bit; // Bit used to test null bit
/**
If true, this field was created in create_tmp_field_from_item from a NULL
value. This means that the type of the field is just a guess, and the type
may be freely coerced to another type.
@see create_tmp_field_from_item
@see Item_type_holder::get_real_type
*/
bool is_created_from_null_item;
Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uchar null_bit_arg,
utype unireg_check_arg, const char *field_name_arg,
@ -934,6 +944,7 @@ public:
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
bool get_time(MYSQL_TIME *ltime);
bool send_binary(Protocol *protocol);
int cmp(const char *,const char*);
void sort_string(char *buff,uint length);
@ -951,6 +962,10 @@ public:
:Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg, cs)
{}
Field_newdate(bool maybe_null_arg, const char *field_name_arg,
struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, table_arg, cs) {}
enum_field_types type() const { return FIELD_TYPE_DATE;}
enum_field_types real_type() const { return FIELD_TYPE_NEWDATE; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }

View file

@ -37,7 +37,8 @@ if (my_b_write((file),(byte*) (from),param->ref_length)) \
static char **make_char_array(char **old_pos, register uint fields,
uint length, myf my_flag);
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffer_file, uint count);
static byte *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
byte *buf);
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
uchar * *sort_keys, IO_CACHE *buffer_file,
IO_CACHE *tempfile,IO_CACHE *indexfile);
@ -238,9 +239,14 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
}
else
{
if (!table_sort.buffpek && table_sort.buffpek_len < maxbuffer &&
!(table_sort.buffpek=
(byte *) read_buffpek_from_file(&buffpek_pointers, maxbuffer)))
if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
{
x_free(table_sort.buffpek);
table_sort.buffpek= 0;
}
if (!(table_sort.buffpek=
read_buffpek_from_file(&buffpek_pointers, maxbuffer,
table_sort.buffpek)))
goto err;
buffpek= (BUFFPEK *) table_sort.buffpek;
table_sort.buffpek_len= maxbuffer;
@ -368,18 +374,20 @@ static char **make_char_array(char **old_pos, register uint fields,
/* Read 'count' number of buffer pointers into memory */
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
static byte *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
byte *buf)
{
ulong length;
BUFFPEK *tmp;
ulong length= sizeof(BUFFPEK)*count;
byte *tmp= buf;
DBUG_ENTER("read_buffpek_from_file");
if (count > UINT_MAX/sizeof(BUFFPEK))
return 0; /* sizeof(BUFFPEK)*count will overflow */
tmp=(BUFFPEK*) my_malloc(length=sizeof(BUFFPEK)*count, MYF(MY_WME));
if (!tmp)
tmp= (byte *)my_malloc(length, MYF(MY_WME));
if (tmp)
{
if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
my_b_read(buffpek_pointers, (byte*) tmp, length))
my_b_read(buffpek_pointers, tmp, length))
{
my_free((char*) tmp, MYF(0));
tmp=0;

View file

@ -4384,7 +4384,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table)
name, table, 0, unsigned_flag);
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATE:
return new Field_date(maybe_null, name, table, &my_charset_bin);
return new Field_newdate(maybe_null, name, table, &my_charset_bin);
case MYSQL_TYPE_TIME:
return new Field_time(maybe_null, name, table, &my_charset_bin);
case MYSQL_TYPE_TIMESTAMP:
@ -6608,6 +6608,8 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
*/
Field *field= ((Item_field *) item)->field;
enum_field_types type= field->real_type();
if (field->is_created_from_null_item)
return MYSQL_TYPE_NULL;
/* work around about varchar type field detection */
if (type == MYSQL_TYPE_STRING && field->type() == MYSQL_TYPE_VAR_STRING)
return MYSQL_TYPE_VAR_STRING;
@ -6859,6 +6861,8 @@ Field *Item_type_holder::make_field_by_type(TABLE *table)
Field::NONE, name,
table, get_set_pack_length(enum_set_typelib->count),
enum_set_typelib, collation.collation);
case MYSQL_TYPE_NULL:
return make_string_field(table);
default:
break;
}

View file

@ -628,7 +628,7 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
*/
switch (args[0]->field_type()) {
case MYSQL_TYPE_DATE:
return new Field_date(maybe_null, name, table, collation.collation);
return new Field_newdate(maybe_null, name, table, collation.collation);
case MYSQL_TYPE_TIME:
return new Field_time(maybe_null, name, table, collation.collation);
case MYSQL_TYPE_TIMESTAMP:
@ -2831,44 +2831,51 @@ String *Item_sum_udf_str::val_str(String *str)
concat of values from "group by" operation
BUGS
DISTINCT and ORDER BY only works if ORDER BY uses all fields and only fields
in expression list
Blobs doesn't work with DISTINCT or ORDER BY
*****************************************************************************/
/*
function of sort for syntax:
GROUP_CONCAT(DISTINCT expr,...)
/**
Compares the values for fields in expr list of GROUP_CONCAT.
@note
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
@return
@retval -1 : key1 < key2
@retval 0 : key1 = key2
@retval 1 : key1 > key2
*/
int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
byte* key2)
int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
const void* key2)
{
Item_func_group_concat* grp_item= (Item_func_group_concat*)arg;
TABLE *table= grp_item->table;
Item **field_item, **end;
Item_func_group_concat *item_func= (Item_func_group_concat*)arg;
TABLE *table= item_func->table;
for (field_item= grp_item->args, end= field_item + grp_item->arg_count_field;
field_item < end;
field_item++)
for (uint i= 0; i < item_func->arg_count_field; i++)
{
Item *item= item_func->args[i];
/*
If field_item is a const item then either get_tp_table_field returns 0
or it is an item over a const table.
*/
if (item->const_item())
continue;
/*
We have to use get_tmp_table_field() instead of
real_item()->get_tmp_table_field() because we want the field in
the temporary table, not the original field
*/
Field *field= (*field_item)->get_tmp_table_field();
/*
If field_item is a const item then either get_tp_table_field returns 0
or it is an item over a const table.
*/
if (field && !(*field_item)->const_item())
{
int res;
uint offset= field->offset() - table->s->null_bytes;
if ((res= field->cmp((char *) key1 + offset, (char *) key2 + offset)))
return res;
}
Field *field= item->get_tmp_table_field();
int res;
uint offset= field->offset()-table->s->null_bytes;
if((res= field->cmp((char*)key1 + offset, (char*)key2 + offset)))
return res;
}
return 0;
}
@ -2879,7 +2886,8 @@ int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
GROUP_CONCAT(expr,... ORDER BY col,... )
*/
int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
int group_concat_key_cmp_with_order(void* arg, const void* key1,
const void* key2)
{
Item_func_group_concat* grp_item= (Item_func_group_concat*) arg;
ORDER **order_item, **end;
@ -2917,25 +2925,6 @@ int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
}
/*
function of sort for syntax:
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
BUG:
This doesn't work in the case when the order by contains data that
is not part of the field list because tree-insert will not notice
the duplicated values when inserting things sorted by ORDER BY
*/
int group_concat_key_cmp_with_distinct_and_order(void* arg,byte* key1,
byte* key2)
{
if (!group_concat_key_cmp_with_distinct(arg,key1,key2))
return 0;
return(group_concat_key_cmp_with_order(arg,key1,key2));
}
/*
Append data from current leaf to item->result
*/
@ -3020,7 +3009,7 @@ Item_func_group_concat(Name_resolution_context *context_arg,
bool distinct_arg, List<Item> *select_list,
SQL_LIST *order_list, String *separator_arg)
:tmp_table_param(0), warning(0),
separator(separator_arg), tree(0), table(0),
separator(separator_arg), tree(0), unique_filter(NULL), table(0),
order(0), context(context_arg),
arg_count_order(order_list ? order_list->elements : 0),
arg_count_field(select_list->elements),
@ -3075,6 +3064,7 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
warning(item->warning),
separator(item->separator),
tree(item->tree),
unique_filter(item->unique_filter),
table(item->table),
order(item->order),
context(item->context),
@ -3125,6 +3115,11 @@ void Item_func_group_concat::cleanup()
delete_tree(tree);
tree= 0;
}
if (unique_filter)
{
delete unique_filter;
unique_filter= NULL;
}
if (warning)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
@ -3154,6 +3149,8 @@ void Item_func_group_concat::clear()
no_appended= TRUE;
if (tree)
reset_tree(tree);
if (distinct)
unique_filter->reset();
/* No need to reset the table as we never call write_row */
}
@ -3177,9 +3174,19 @@ bool Item_func_group_concat::add()
}
null_value= FALSE;
bool row_eligible= TRUE;
if (distinct)
{
/* Filter out duplicate rows. */
uint count= unique_filter->elements_in_tree();
unique_filter->unique_add(table->record[0] + table->s->null_bytes);
if (count == unique_filter->elements_in_tree())
row_eligible= FALSE;
}
TREE_ELEMENT *el= 0; // Only for safety
if (tree)
if (row_eligible && tree)
el= tree_insert(tree, table->record[0] + table->s->null_bytes, 0,
tree->custom_arg);
/*
@ -3187,7 +3194,7 @@ bool Item_func_group_concat::add()
we can dump the row here in case of GROUP_CONCAT(DISTINCT...)
instead of doing tree traverse later.
*/
if (!warning_for_row &&
if (row_eligible && !warning_for_row &&
(!tree || (el->count == 1 && distinct && !arg_count_order)))
dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
@ -3263,7 +3270,6 @@ bool Item_func_group_concat::setup(THD *thd)
{
List<Item> list;
SELECT_LEX *select_lex= thd->lex->current_select;
qsort_cmp2 compare_key;
DBUG_ENTER("Item_func_group_concat::setup");
/*
@ -3353,38 +3359,33 @@ bool Item_func_group_concat::setup(THD *thd)
table->file->extra(HA_EXTRA_NO_ROWS);
table->no_rows= 1;
/*
Need sorting or uniqueness: init tree and choose a function to sort.
Don't reserve space for NULLs: if any of gconcat arguments is NULL,
the row is not added to the result.
*/
uint tree_key_length= table->s->reclength - table->s->null_bytes;
if (distinct || arg_count_order)
if (arg_count_order)
{
/*
Need sorting: init tree and choose a function to sort.
Don't reserve space for NULLs: if any of gconcat arguments is NULL,
the row is not added to the result.
*/
uint tree_key_length= table->s->reclength - table->s->null_bytes;
tree= &tree_base;
if (arg_count_order)
{
if (distinct)
compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct_and_order;
else
compare_key= (qsort_cmp2) group_concat_key_cmp_with_order;
}
else
{
compare_key= (qsort_cmp2) group_concat_key_cmp_with_distinct;
}
/*
Create a tree for sorting. The tree is used to sort and to remove
duplicate values (according to the syntax of this function). If there
is no DISTINCT or ORDER BY clauses, we don't create this tree.
Create a tree for sorting. The tree is used to sort (according to the
syntax of this function). If there is no ORDER BY clause, we don't
create this tree.
*/
init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
thd->variables.sortbuff_size/16), 0,
tree_key_length, compare_key, 0, NULL, (void*) this);
tree_key_length,
group_concat_key_cmp_with_order , 0, NULL, (void*) this);
}
if (distinct)
unique_filter= new Unique(group_concat_key_cmp_with_distinct,
(void*)this,
tree_key_length,
thd->variables.max_heap_table_size);
DBUG_RETURN(FALSE);
}
@ -3454,3 +3455,10 @@ void Item_func_group_concat::print(String *str)
str->append(*separator);
str->append(STRING_WITH_LEN("\')"));
}
Item_func_group_concat::~Item_func_group_concat()
{
if (unique_filter)
delete unique_filter;
}

View file

@ -1173,11 +1173,22 @@ class Item_func_group_concat : public Item_sum
String *separator;
TREE tree_base;
TREE *tree;
/**
If DISTINCT is used with this GROUP_CONCAT, this member is used to filter
out duplicates.
@see Item_func_group_concat::setup
@see Item_func_group_concat::add
@see Item_func_group_concat::clear
*/
Unique *unique_filter;
TABLE *table;
ORDER **order;
Name_resolution_context *context;
uint arg_count_order; // total count of ORDER BY items
uint arg_count_field; // count of arguments
/** The number of ORDER BY items. */
uint arg_count_order;
/** The number of selected items, aka the expr list. */
uint arg_count_field;
uint count_cut_values;
bool distinct;
bool warning_for_row;
@ -1190,13 +1201,10 @@ class Item_func_group_concat : public Item_sum
*/
Item_func_group_concat *original;
friend int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
byte* key2);
friend int group_concat_key_cmp_with_order(void* arg, byte* key1,
byte* key2);
friend int group_concat_key_cmp_with_distinct_and_order(void* arg,
byte* key1,
byte* key2);
friend int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
const void* key2);
friend int group_concat_key_cmp_with_order(void* arg, const void* key1,
const void* key2);
friend int dump_leaf_key(byte* key,
element_count count __attribute__((unused)),
Item_func_group_concat *group_concat_item);
@ -1207,7 +1215,7 @@ public:
SQL_LIST *is_order, String *is_separator);
Item_func_group_concat(THD *thd, Item_func_group_concat *item);
~Item_func_group_concat() {}
~Item_func_group_concat();
void cleanup();
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}

View file

@ -3303,7 +3303,7 @@ Field *Item_func_str_to_date::tmp_table_field(TABLE *t_arg)
if (cached_field_type == MYSQL_TYPE_TIME)
return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
if (cached_field_type == MYSQL_TYPE_DATE)
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
return (new Field_newdate(maybe_null, name, t_arg, &my_charset_bin));
if (cached_field_type == MYSQL_TYPE_DATETIME)
return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
return (new Field_string(max_length, maybe_null, name, t_arg, &my_charset_bin));
@ -3415,6 +3415,8 @@ bool Item_func_last_day::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
ltime->day= days_in_month[month_idx];
if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366)
ltime->day= 29;
ltime->hour= ltime->minute= ltime->second= 0;
ltime->second_part= 0;
ltime->time_type= MYSQL_TIMESTAMP_DATE;
return 0;
}

View file

@ -340,7 +340,7 @@ public:
}
Field *tmp_table_field(TABLE *t_arg)
{
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
return (new Field_newdate(maybe_null, name, t_arg, &my_charset_bin));
}
bool result_as_longlong() { return TRUE; }
my_decimal *val_decimal(my_decimal *decimal_value)
@ -784,7 +784,7 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
Field *tmp_table_field(TABLE *t_arg)
{
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
return (new Field_newdate(maybe_null, name, t_arg, &my_charset_bin));
}
void fix_length_and_dec()
{
@ -884,7 +884,7 @@ public:
}
Field *tmp_table_field(TABLE *t_arg)
{
return (new Field_date(maybe_null, name, t_arg, &my_charset_bin));
return (new Field_newdate(maybe_null, name, t_arg, &my_charset_bin));
}
longlong val_int();
my_decimal *val_decimal(my_decimal *decimal_value)

View file

@ -1284,10 +1284,10 @@ err:
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
{
uint dir_len = dirname_length(log_file_name);
if (dir_len > FN_REFLEN)
if (dir_len >= FN_REFLEN)
dir_len=FN_REFLEN-1;
strnmov(buf, log_file_name, dir_len);
strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len);
strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len -1);
}

View file

@ -922,7 +922,7 @@ bool load_master_data(THD* thd)
0, (SLAVE_IO | SLAVE_SQL)))
my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
strmake(active_mi->master_log_name, row[0],
sizeof(active_mi->master_log_name));
sizeof(active_mi->master_log_name) -1);
active_mi->master_log_pos= my_strtoll10(row[1], (char**) 0, &error_2);
/* at least in recent versions, the condition below should be false */
if (active_mi->master_log_pos < BIN_LOG_HEADER_SIZE)

View file

@ -1895,7 +1895,7 @@ sp_use_new_db(THD *thd, LEX_STRING new_db, LEX_STRING *old_db,
if (thd->db)
{
old_db->length= (strmake(old_db->str, thd->db, old_db->length) -
old_db->length= (strmake(old_db->str, thd->db, old_db->length - 1) -
old_db->str);
}
else

View file

@ -4254,7 +4254,36 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
*resolution= RESOLVED_IGNORING_ALIAS;
break;
}
}
}
else if (table_name && item->type() == Item::REF_ITEM &&
((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF)
{
/*
TODO:Here we process prefixed view references only. What we should
really do is process all types of Item_refs. But this will currently
lead to a clash with the way references to outer SELECTs (from the
HAVING clause) are handled in e.g. :
SELECT 1 FROM t1 AS t1_o GROUP BY a
HAVING (SELECT t1_o.a FROM t1 AS t1_i GROUP BY t1_i.a LIMIT 1).
Processing all Item_refs here will cause t1_o.a to resolve to itself.
We still need to process the special case of Item_direct_view_ref
because in the context of views they have the same meaning as
Item_field for tables.
*/
Item_ident *item_ref= (Item_ident *) item;
if (item_ref->name && item_ref->table_name &&
!my_strcasecmp(system_charset_info, item_ref->name, field_name) &&
!my_strcasecmp(table_alias_charset, item_ref->table_name,
table_name) &&
(!db_name || (item_ref->db_name &&
!strcmp (item_ref->db_name, db_name))))
{
found= li.ref();
*counter= i;
*resolution= RESOLVED_IGNORING_ALIAS;
break;
}
}
}
if (!found)
{

View file

@ -931,6 +931,7 @@ void THD::rollback_item_tree_changes()
select_result::select_result()
{
thd=current_thd;
nest_level= -1;
}
void select_result::send_error(uint errcode,const char *err)

View file

@ -1912,6 +1912,7 @@ class select_result :public Sql_alloc {
protected:
THD *thd;
SELECT_LEX_UNIT *unit;
uint nest_level;
public:
select_result();
virtual ~select_result() {};
@ -1948,6 +1949,12 @@ public:
*/
virtual void cleanup();
void set_thd(THD *thd_arg) { thd= thd_arg; }
/**
The nest level, if supported.
@return
-1 if nest level is undefined, otherwise a positive integer.
*/
int get_nest_level() { return nest_level; }
#ifdef EMBEDDED_LIBRARY
virtual void begin_dataset() {}
#else
@ -2034,7 +2041,14 @@ class select_export :public select_to_file {
bool is_unsafe_field_sep;
bool fixed_row_size;
public:
select_export(sql_exchange *ex) :select_to_file(ex) {}
/**
Creates a select_export to represent INTO OUTFILE <filename> with a
defined level of subquery nesting.
*/
select_export(sql_exchange *ex, uint nest_level_arg) :select_to_file(ex)
{
nest_level= nest_level_arg;
}
~select_export();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items);
@ -2043,7 +2057,15 @@ public:
class select_dump :public select_to_file {
public:
select_dump(sql_exchange *ex) :select_to_file(ex) {}
/**
Creates a select_export to represent INTO DUMPFILE <filename> with a
defined level of subquery nesting.
*/
select_dump(sql_exchange *ex, uint nest_level_arg) :
select_to_file(ex)
{
nest_level= nest_level_arg;
}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items);
};
@ -2461,7 +2483,16 @@ class select_dumpvar :public select_result_interceptor {
ha_rows row_count;
public:
List<my_var> var_list;
select_dumpvar() { var_list.empty(); row_count= 0;}
/**
Creates a select_dumpvar to represent INTO <variable> with a defined
level of subquery nesting.
*/
select_dumpvar(uint nest_level_arg)
{
var_list.empty();
row_count= 0;
nest_level= nest_level_arg;
}
~select_dumpvar() {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_data(List<Item> &items);

View file

@ -9041,6 +9041,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
*((*copy_func)++) = item; // Save for copy_funcs
if (modify_item)
item->set_result_field(new_field);
if (item->type() == Item::NULL_ITEM)
new_field->is_created_from_null_item= TRUE;
return new_field;
}

View file

@ -4211,6 +4211,14 @@ select_paren:
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
if (sel->linkage == UNION_TYPE &&
sel->olap != UNSPECIFIED_OLAP_TYPE &&
sel->master_unit()->fake_select_lex)
{
my_error(ER_WRONG_USAGE, MYF(0),
"CUBE/ROLLUP", "ORDER BY");
MYSQL_YYABORT;
}
/* select in braces, can't contain global parameters */
if (sel->master_unit()->fake_select_lex)
sel->master_unit()->global_parameters=
@ -6165,7 +6173,8 @@ order_clause:
SELECT_LEX *sel= lex->current_select;
SELECT_LEX_UNIT *unit= sel-> master_unit();
if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
sel->olap != UNSPECIFIED_OLAP_TYPE)
sel->olap != UNSPECIFIED_OLAP_TYPE &&
(sel->linkage != UNION_TYPE || sel->braces))
{
my_error(ER_WRONG_USAGE, MYF(0),
"CUBE/ROLLUP", "ORDER BY");
@ -6341,7 +6350,8 @@ procedure_item:
select_var_list_init:
{
LEX *lex=Lex;
if (!lex->describe && (!(lex->result= new select_dumpvar())))
if (!lex->describe &&
(!(lex->result= new select_dumpvar(lex->nest_level))))
MYSQL_YYABORT;
}
select_var_list
@ -6415,7 +6425,7 @@ into_destination:
LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
if (!(lex->exchange= new sql_exchange($2.str, 0)) ||
!(lex->result= new select_export(lex->exchange)))
!(lex->result= new select_export(lex->exchange, lex->nest_level)))
MYSQL_YYABORT;
}
opt_field_term opt_line_term
@ -6427,7 +6437,7 @@ into_destination:
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
if (!(lex->exchange= new sql_exchange($2.str,1)))
MYSQL_YYABORT;
if (!(lex->result= new select_dump(lex->exchange)))
if (!(lex->result= new select_dump(lex->exchange, lex->nest_level)))
MYSQL_YYABORT;
}
}
@ -9418,12 +9428,18 @@ union_list:
UNION_SYM union_option
{
LEX *lex=Lex;
if (lex->result)
{
/* Only the last SELECT can have INTO...... */
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
MYSQL_YYABORT;
}
if (lex->result &&
(lex->result->get_nest_level() == -1 ||
lex->result->get_nest_level() == lex->nest_level))
{
/*
Only the last SELECT can have INTO unless the INTO and UNION
are at different nest levels. In version 5.1 and above, INTO
will onle be allowed at top level.
*/
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
MYSQL_YYABORT;
}
if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
{
my_parse_error(ER(ER_SYNTAX_ERROR));

View file

@ -165,6 +165,14 @@ bool mysql_create_frm(THD *thd, my_string file_name,
strmake((char*) forminfo+47, create_info->comment.str ?
create_info->comment.str : "", create_info->comment.length);
forminfo[46]=(uchar) create_info->comment.length;
#ifdef EXTRA_DEBUG
/*
EXTRA_DEBUG causes strmake() to initialize its buffer behind the
payload with a magic value to detect wrong buffer-sizes. We
explicitly zero that segment again.
*/
memset((char*) forminfo+47 + forminfo[46], 0, 61 - forminfo[46]);
#endif
if (my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW) ||
my_pwrite(file,(byte*) keybuff,key_info_length,
(ulong) uint2korr(fileinfo+6),MYF_RW))

View file

@ -27,23 +27,25 @@
#include <my_global.h>
#include "m_string.h"
#ifdef BAD_STRING_COMPILER
char *strmake(char *dst,const char *src,uint length)
{
reg1 char *res;
if ((res=memccpy(dst,src,0,length)))
return res-1;
dst[length]=0;
return dst+length;
}
#define strmake strmake_overlapp /* Use orginal for overlapping str */
#endif
char *strmake(register char *dst, register const char *src, uint length)
{
#ifdef EXTRA_DEBUG
/*
'length' is the maximum length of the string; the buffer needs
to be one character larger to accomodate the terminating '\0'.
This is easy to get wrong, so we make sure we write to the
entire length of the buffer to identify incorrect buffer-sizes.
We only initialise the "unused" part of the buffer here, a) for
efficiency, and b) because dst==src is allowed, so initialising
the entire buffer would overwrite the source-string. Also, we
write a character rather than '\0' as this makes spotting these
problems in the results easier.
*/
uint n= strlen(src) + 1;
if (n <= length)
memset(dst + n, (int) 'Z', length - n + 1);
#endif
while (length--)
if (! (*dst++ = *src++))
return dst-1;