Commit cab4a776 authored by Alexey Kopytov's avatar Alexey Kopytov

Manual merge of mysql-5.1-bugteam into mysql-trunk-merge.

Conflicts:

Text conflict in storage/myisam/mi_delete_table.c
parents 3514d882 92a41960
......@@ -4899,3 +4899,92 @@ WHERE t1.a = d1.a;
ERROR 42S22: Unknown column 'd1.a' in 'where clause'
DROP TABLE t1;
End of 5.1 tests.
Set up test tables.
CREATE TABLE t1 (
t1_id INT UNSIGNED,
PRIMARY KEY(t1_id)
) Engine=MyISAM;
INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
CREATE TABLE t2 SELECT * FROM t1;
CREATE TABLE t3 (
t3_id INT UNSIGNED AUTO_INCREMENT,
t1_id INT UNSIGNED,
amount DECIMAL(16,2),
PRIMARY KEY(t3_id),
KEY(t1_id)
) Engine=MyISAM;
INSERT INTO t3 (t1_id, t3_id, amount)
VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
This is the 'inner query' running by itself.
Produces correct results.
SELECT
t1.t1_id,
IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
FROM
t1
LEFT JOIN t2 ON t2.t1_id=t1.t1_id
GROUP BY
t1.t1_id
;
t1_id total_amount
1 100.00
2 200.00
3 0.00
4 400.00
5 0.00
SELECT * FROM (the same inner query)
Produces correct results.
SELECT * FROM (
SELECT
t1.t1_id,
IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
FROM
t1
LEFT JOIN t2 ON t2.t1_id=t1.t1_id
GROUP BY
t1.t1_id
) AS t;
t1_id total_amount
1 100.00
2 200.00
3 0.00
4 400.00
5 0.00
Now make t2.t1_id part of a key.
ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
Same inner query by itself.
Still correct results.
SELECT
t1.t1_id,
IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
FROM
t1
LEFT JOIN t2 ON t2.t1_id=t1.t1_id
GROUP BY
t1.t1_id;
t1_id total_amount
1 100.00
2 200.00
3 0
4 400.00
5 0
SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
SELECT * FROM (
SELECT
t1.t1_id,
IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
FROM
t1
LEFT JOIN t2 ON t2.t1_id=t1.t1_id
GROUP BY
t1.t1_id
) AS t;
t1_id total_amount
1 100.00
2 200.00
3 0.00
4 400.00
5 0.00
DROP TABLE t3;
DROP TABLE t2;
DROP TABLE t1;
......@@ -168,4 +168,16 @@ Warning 1618 <DATA DIRECTORY> option ignored
Warning 1618 <INDEX DIRECTORY> option ignored
DROP TABLE t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
#
# BUG#40980 - Drop table can remove another MyISAM table's
# data and index files
#
CREATE TABLE user(a INT) DATA DIRECTORY='MYSQL_TMP_DIR/mysql'
INDEX DIRECTORY='MYSQL_TMP_DIR/mysql';
FLUSH TABLE user;
# Symlinking mysql database to tmpdir
FLUSH TABLE mysql.user;
DROP TABLE user;
FLUSH TABLE mysql.user;
SELECT * FROM mysql.user;
End of 5.1 tests
......@@ -3838,3 +3838,86 @@ DROP TABLE t1;
--echo End of 5.1 tests.
#
# Bug #47904 Incorrect results w/ table subquery, derived SQs, and LEFT JOIN on index
#
--echo Set up test tables.
CREATE TABLE t1 (
t1_id INT UNSIGNED,
PRIMARY KEY(t1_id)
) Engine=MyISAM;
INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
CREATE TABLE t2 SELECT * FROM t1;
CREATE TABLE t3 (
t3_id INT UNSIGNED AUTO_INCREMENT,
t1_id INT UNSIGNED,
amount DECIMAL(16,2),
PRIMARY KEY(t3_id),
KEY(t1_id)
) Engine=MyISAM;
INSERT INTO t3 (t1_id, t3_id, amount)
VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
--echo This is the 'inner query' running by itself.
--echo Produces correct results.
SELECT
t1.t1_id,
IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
FROM
t1
LEFT JOIN t2 ON t2.t1_id=t1.t1_id
GROUP BY
t1.t1_id
;
--echo SELECT * FROM (the same inner query)
--echo Produces correct results.
SELECT * FROM (
SELECT
t1.t1_id,
IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
FROM
t1
LEFT JOIN t2 ON t2.t1_id=t1.t1_id
GROUP BY
t1.t1_id
) AS t;
--echo Now make t2.t1_id part of a key.
ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
--echo Same inner query by itself.
--echo Still correct results.
SELECT
t1.t1_id,
IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
FROM
t1
LEFT JOIN t2 ON t2.t1_id=t1.t1_id
GROUP BY
t1.t1_id;
--echo SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
SELECT * FROM (
SELECT
t1.t1_id,
IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
FROM
t1
LEFT JOIN t2 ON t2.t1_id=t1.t1_id
GROUP BY
t1.t1_id
) AS t;
DROP TABLE t3;
DROP TABLE t2;
DROP TABLE t1;
......@@ -249,4 +249,26 @@ eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTO
DROP TABLE t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
--echo #
--echo # BUG#40980 - Drop table can remove another MyISAM table's
--echo # data and index files
--echo #
--mkdir $MYSQL_TMP_DIR/mysql
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
eval CREATE TABLE user(a INT) DATA DIRECTORY='$MYSQL_TMP_DIR/mysql'
INDEX DIRECTORY='$MYSQL_TMP_DIR/mysql';
FLUSH TABLE user;
--echo # Symlinking mysql database to tmpdir
--remove_file $MYSQL_TMP_DIR/mysql/user.MYD
--remove_file $MYSQL_TMP_DIR/mysql/user.MYI
--rmdir $MYSQL_TMP_DIR/mysql
--exec ln -s $MYSQLD_DATADIR/mysql $MYSQL_TMP_DIR/mysql
FLUSH TABLE mysql.user;
DROP TABLE user;
FLUSH TABLE mysql.user;
--disable_result_log
SELECT * FROM mysql.user;
--enable_result_log
--remove_file $MYSQL_TMP_DIR/mysql
--echo End of 5.1 tests
......@@ -3750,7 +3750,7 @@ void Item_copy_decimal::copy()
{
my_decimal *nr= item->val_decimal(&cached_value);
if (nr && nr != &cached_value)
memcpy (&cached_value, nr, sizeof (my_decimal));
my_decimal2decimal (nr, &cached_value);
null_value= item->null_value;
}
......
......@@ -19,6 +19,41 @@
#include "fulltext.h"
/**
Remove MyISAM data/index file safely
@details
If name is a symlink and file it is pointing to is not in
data directory, file is also removed.
@param name file to remove
@returns
0 on success or my_errno on failure
*/
static int _mi_safe_delete_file(const char *name)
{
DBUG_ENTER("_mi_safe_delete_file");
if (my_is_symlink(name) && (*myisam_test_invalid_symlink)(name))
{
/*
Symlink is pointing to file in data directory.
Remove symlink, keep file.
*/
if (my_delete(name, MYF(MY_WME)))
DBUG_RETURN(my_errno);
}
else
{
if (my_delete_with_symlink(name, MYF(MY_WME)))
DBUG_RETURN(my_errno);
}
DBUG_RETURN(0);
}
int mi_delete_table(const char *name)
{
char from[FN_REFLEN];
......@@ -58,13 +93,39 @@ int mi_delete_table(const char *name)
#endif /* USE_RAID */
fn_format(from,name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
if (mysql_file_delete_with_symlink(mi_key_file_kfile, from, MYF(MY_WME)))
if (my_is_symlink(from) && (*myisam_test_invalid_symlink)(from))
{
/*
Symlink is pointing to file in data directory.
Remove symlink, keep file.
*/
if (mysql_file_delete(mi_key_file_kfile, from, MYF(MY_WME)))
DBUG_RETURN(my_errno);
}
else
{
if (mysql_file_delete_with_symlink(mi_key_file_kfile, from, MYF(MY_WME)))
DBUG_RETURN(my_errno);
}
DBUG_RETURN(my_errno);
fn_format(from,name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
#ifdef USE_RAID
if (raid_type)
DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0);
#endif
DBUG_RETURN(mysql_file_delete_with_symlink(mi_key_file_dfile,
from, MYF(MY_WME)) ? my_errno : 0);
if (my_is_symlink(from) && (*myisam_test_invalid_symlink)(from))
{
/*
Symlink is pointing to file in data directory.
Remove symlink, keep file.
*/
if (mysql_file_delete(mi_key_file_dfile, from, MYF(MY_WME)))
DBUG_RETURN(my_errno);
}
else
{
if (mysql_file_delete_with_symlink(mi_key_file_dfile, from, MYF(MY_WME)))
DBUG_RETURN(my_errno);
}
DBUG_RETURN(0);
}
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