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

into  kaamos.(none):/data/src/opt/mysql-5.1-opt


client/mysql.cc:
  Auto merged
client/mysqltest.c:
  Auto merged
sql/log.cc:
  Auto merged
sql/repl_failsafe.cc:
  Auto merged
sql/set_var.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_db.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_show.cc:
  Auto merged
This commit is contained in:
unknown 2008-01-10 20:44:23 +03:00
commit 824ced465e
41 changed files with 678 additions and 149 deletions

View file

@ -3113,7 +3113,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

@ -590,7 +590,9 @@ static void write_header(FILE *sql_file, char *db_name)
{
if (opt_comments)
{
fprintf(sql_file, "-- MySQL dump %s\n--\n", DUMP_VERSION);
fprintf(sql_file,
"-- MySQL dump %s Distrib %s, for %s (%s)\n--\n",
DUMP_VERSION, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
fprintf(sql_file, "-- Host: %s Database: %s\n",
current_host ? current_host : "localhost", db_name ? db_name :
"");

View file

@ -3654,7 +3654,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);
}
@ -6975,7 +6975,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

@ -0,0 +1,35 @@
set autocommit=1;
reset master;
create table bug16206 (a int);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
f n Query 1 n use `test`; create table bug16206 (a int)
f n Query 1 n use `test`; insert into bug16206 values(1)
f n Query 1 n use `test`; insert into bug16206 values(2)
drop table bug16206;
reset master;
create table bug16206 (a int) engine= bdb;
insert into bug16206 values(0);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
insert into bug16206 values(3);
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb
f n Query 1 n use `test`; insert into bug16206 values(0)
f n Query 1 n use `test`; insert into bug16206 values(1)
f n Query 1 n use `test`; BEGIN
f n Query 1 n use `test`; insert into bug16206 values(2)
f n Query 1 n use `test`; COMMIT
f n Query 1 n use `test`; insert into bug16206 values(3)
drop table bug16206;
set autocommit=0;
End of 5.0 tests

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);
@ -876,4 +876,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

@ -1398,4 +1398,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 filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 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

@ -1258,6 +1258,9 @@ 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
select date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND);
date_sub("0050-01-01 00:00:01",INTERVAL 2 SECOND)

View file

@ -72,10 +72,6 @@ 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
#
# Bug#29817 Queries with UDF fail with non-descriptive error

View file

@ -4282,6 +4282,15 @@ 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.
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);

View file

@ -260,6 +260,11 @@ 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
create table t1 (a date, primary key (a))engine=memory;
insert into t1 values ('0000-01-01'), ('0000-00-01'), ('0001-01-01');

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 Incorrect datetime value: '0000-00-00'
Warning 1292 Incorrect datetime value: '0000-00-00'
Warning 1292 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

@ -1445,4 +1445,79 @@ 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), (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

@ -91,21 +91,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

@ -101,10 +101,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;
@ -119,10 +121,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

@ -0,0 +1,38 @@
-- source include/not_embedded.inc
-- source include/have_bdb.inc
#
# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode
#
set autocommit=1;
let $VERSION=`select version()`;
reset master;
create table bug16206 (a int);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
--replace_result $VERSION VERSION
--replace_column 1 f 2 n 5 n
show binlog events;
drop table bug16206;
reset master;
create table bug16206 (a int) engine= bdb;
insert into bug16206 values(0);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
insert into bug16206 values(3);
--replace_result $VERSION VERSION
--replace_column 1 f 2 n 5 n
show binlog events;
drop table bug16206;
set autocommit=0;
--echo 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

@ -908,5 +908,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

@ -776,6 +776,13 @@ 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

@ -122,16 +122,6 @@ select count(*) from information_schema.COLUMN_PRIVILEGES;
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
--echo #

View file

@ -3136,6 +3136,28 @@ 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.
@ -3165,6 +3187,7 @@ SELECT a FROM t1 t0
SET @@sql_mode=default;
DROP TABLE t1;
#
# Bug#20835 (literal string with =any values)
#
CREATE TABLE t1 (s1 char(1));

View file

@ -213,6 +213,14 @@ 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

@ -922,4 +922,70 @@ 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#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

@ -282,7 +282,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
@ -408,7 +408,7 @@ size_t unpack_filename(char * 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 */
size_t system_filename(char * to, const char *from)
{

View file

@ -1307,7 +1307,8 @@ Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
field_name(field_name_arg),
key_start(0), part_of_key(0), part_of_key_not_clustered(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*) "";
@ -5636,6 +5637,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 uchar *a_ptr, const uchar *b_ptr)
{
int32 a,b;

View file

@ -90,6 +90,16 @@ public:
uint32 flags;
uint16 field_index; // field number in fields array
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(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
@ -1240,6 +1250,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 uchar *,const uchar *);
void sort_string(uchar *buff,uint length);
@ -1258,6 +1269,10 @@ public:
:Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, cs)
{}
Field_newdate(bool maybe_null_arg, const char *field_name_arg,
CHARSET_INFO *cs)
:Field_str((uchar*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, cs) {}
enum_field_types type() const { return MYSQL_TYPE_DATE;}
enum_field_types real_type() const { return MYSQL_TYPE_NEWDATE; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }

View file

@ -37,7 +37,8 @@ if (my_b_write((file),(uchar*) (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 uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
uchar *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);
@ -244,9 +245,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=
(uchar *) 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=
(uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
table_sort.buffpek)))
goto err;
buffpek= (BUFFPEK *) table_sort.buffpek;
table_sort.buffpek_len= maxbuffer;
@ -374,14 +380,16 @@ 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 uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
uchar *buf)
{
ulong length;
BUFFPEK *tmp;
ulong length= sizeof(BUFFPEK)*count;
uchar *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= (uchar *)my_malloc(length, MYF(MY_WME));
if (tmp)
{
if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||

View file

@ -4467,7 +4467,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
break;
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATE:
field= new Field_date(maybe_null, name, &my_charset_bin);
field= new Field_newdate(maybe_null, name, &my_charset_bin);
break;
case MYSQL_TYPE_TIME:
field= new Field_time(maybe_null, name, &my_charset_bin);
@ -6707,6 +6707,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;
@ -6965,6 +6967,8 @@ Field *Item_type_holder::make_field_by_type(TABLE *table)
if (field)
field->init(table);
return field;
case MYSQL_TYPE_NULL:
return make_string_field(table);
default:
break;
}

View file

@ -633,7 +633,7 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
*/
switch (args[0]->field_type()) {
case MYSQL_TYPE_DATE:
field= new Field_date(maybe_null, name, collation.collation);
field= new Field_newdate(maybe_null, name, collation.collation);
break;
case MYSQL_TYPE_TIME:
field= new Field_time(maybe_null, name, collation.collation);
@ -2849,45 +2849,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, uchar* key1,
uchar* 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_tmp_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(field->table->record[0]) -
table->s->null_bytes);
if ((res= field->cmp(key1 + offset, key2 + offset)))
return res;
}
Field *field= item->get_tmp_table_field();
int res;
uint offset= field->offset(field->table->record[0])-table->s->null_bytes;
if((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
return res;
}
return 0;
}
@ -2898,7 +2904,8 @@ int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
GROUP_CONCAT(expr,... ORDER BY col,... )
*/
int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* 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;
@ -2924,7 +2931,7 @@ int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
int res;
uint offset= (field->offset(field->table->record[0]) -
table->s->null_bytes);
if ((res= field->cmp(key1 + offset, key2 + offset)))
if ((res= field->cmp((uchar*)key1 + offset, (uchar*)key2 + offset)))
return (*order_item)->asc ? res : -res;
}
}
@ -2937,25 +2944,6 @@ int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* 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,uchar* key1,
uchar* 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
*/
@ -3041,7 +3029,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),
@ -3096,6 +3084,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),
@ -3146,6 +3135,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];
@ -3175,6 +3169,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 */
}
@ -3198,9 +3194,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);
/*
@ -3208,7 +3214,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);
@ -3284,7 +3290,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");
/*
@ -3374,38 +3379,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);
}
@ -3475,3 +3475,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, uchar* key1,
uchar* key2);
friend int group_concat_key_cmp_with_order(void* arg, uchar* key1,
uchar* key2);
friend int group_concat_key_cmp_with_distinct_and_order(void* arg,
uchar* key1,
uchar* 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(uchar* 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

@ -3344,6 +3344,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

@ -3005,10 +3005,10 @@ err:
void MYSQL_BIN_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

@ -927,7 +927,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

@ -6400,7 +6400,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

@ -1396,7 +1396,7 @@ static void backup_current_db_name(THD *thd,
}
else
{
strmake(saved_db_name->str, thd->db, saved_db_name->length);
strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
saved_db_name->length= thd->db_length;
}
}

View file

@ -9276,6 +9276,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

@ -6151,6 +6151,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=
@ -8039,7 +8047,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");

View file

@ -227,6 +227,14 @@ bool mysql_create_frm(THD *thd, const char *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
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (part_info)
{

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, size_t 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;