2653 Joerg Bruehe 2008-09-10 [merge]
Merge main 5.0 into 5.0-build.
modified:
include/my_sys.h
include/myisam.h
myisam/mi_check.c
myisam/mi_create.c
myisam/mi_open.c
myisam/mi_static.c
myisam/myisamchk.c
myisam/myisamdef.h
myisam/rt_index.c
mysql-test/r/group_min_max.result
mysql-test/r/myisam.result
mysql-test/r/symlink.result
mysql-test/r/type_bit.result
mysql-test/r/udf.result
mysql-test/t/group_min_max.test
mysql-test/t/myisam.test
mysql-test/t/symlink.test
mysql-test/t/type_bit.test
mysys/my_symlink.c
mysys/thr_lock.c
sql/field.h
sql/mysql_priv.h
sql/mysqld.cc
sql/opt_range.cc
sql/opt_range.h
sql/set_var.cc
sql/sql_parse.cc
sql/sql_select.cc
sql/sql_udf.cc
sql/unireg.h
2652 timothy.smith@stripped 2008-09-05
Merge from mysql-5.0.68-release
=== modified file 'include/my_sys.h'
--- a/include/my_sys.h 2008-07-16 22:58:45 +0000
+++ b/include/my_sys.h 2008-08-22 12:31:53 +0000
@@ -574,6 +574,7 @@ extern int my_close(File Filedes,myf MyF
extern File my_dup(File file, myf MyFlags);
extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
extern int my_readlink(char *to, const char *filename, myf MyFlags);
+extern int my_is_symlink(const char *filename);
extern int my_realpath(char *to, const char *filename, myf MyFlags);
extern File my_create_with_symlink(const char *linkname, const char *filename,
int createflags, int access_flags,
=== modified file 'include/myisam.h'
--- a/include/myisam.h 2006-12-23 19:17:15 +0000
+++ b/include/myisam.h 2008-08-22 12:31:53 +0000
@@ -267,6 +267,10 @@ extern my_bool myisam_flush,myisam_delay
extern my_off_t myisam_max_temp_length;
extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size;
+/* usually used to check if a symlink points into the mysql data home */
+/* which is normally forbidden */
+extern int (*myisam_test_invalid_symlink)(const char *filename);
+
/* Prototypes for myisam-functions */
extern int mi_close(struct st_myisam_info *file);
=== modified file 'myisam/mi_check.c'
--- a/myisam/mi_check.c 2008-03-29 15:50:46 +0000
+++ b/myisam/mi_check.c 2008-08-22 12:31:53 +0000
@@ -1732,7 +1732,7 @@ err:
DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share,-1))
+ mi_open_datafile(info,share,name,-1))
got_error=1;
}
}
@@ -2519,7 +2519,7 @@ err:
DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share,-1))
+ mi_open_datafile(info,share,name,-1))
got_error=1;
}
}
@@ -3050,7 +3050,7 @@ err:
DATA_TMP_EXT, share->base.raid_chunks,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share,-1))
+ mi_open_datafile(info,share,name,-1))
got_error=1;
}
}
=== modified file 'myisam/mi_create.c'
--- a/myisam/mi_create.c 2007-07-11 09:37:47 +0000
+++ b/myisam/mi_create.c 2008-08-26 13:48:50 +0000
@@ -192,7 +192,7 @@ int mi_create(const char *name,uint keys
packed=(packed+7)/8;
if (pack_reclength != INT_MAX32)
pack_reclength+= reclength+packed +
- test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_PACK_RECORD));
+ test(test_all_bits(options, HA_OPTION_CHECKSUM | HA_OPTION_PACK_RECORD));
min_pack_length+=packed;
if (!ci->data_file_length && ci->max_rows)
=== modified file 'myisam/mi_open.c'
--- a/myisam/mi_open.c 2008-03-29 07:52:16 +0000
+++ b/myisam/mi_open.c 2008-08-22 12:31:53 +0000
@@ -74,7 +74,7 @@ MI_INFO *test_if_reopen(char *filename)
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
{
- int lock_error,kfile,open_mode,save_errno,have_rtree=0;
+ int lock_error,kfile,open_mode,save_errno,have_rtree=0, realpath_err;
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
key_parts,unique_key_parts,fulltext_keys,uniques;
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
@@ -94,7 +94,16 @@ MI_INFO *mi_open(const char *name, int m
head_length=sizeof(share_buff.state.header);
bzero((byte*) &info,sizeof(info));
- my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0));
+ realpath_err= my_realpath(name_buff,
+ fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0));
+ if (my_is_symlink(org_name) &&
+ (realpath_err || (*myisam_test_invalid_symlink)(name_buff)))
+ {
+ my_errno= HA_WRONG_CREATE_OPTION;
+ DBUG_RETURN (NULL);
+ }
+
+
pthread_mutex_lock(&THR_LOCK_myisam);
if (!(old_info=test_if_reopen(name_buff)))
{
@@ -463,7 +472,7 @@ MI_INFO *mi_open(const char *name, int m
lock_error=1; /* Database unlocked */
}
- if (mi_open_datafile(&info, share, -1))
+ if (mi_open_datafile(&info, share, name, -1))
goto err;
errpos=5;
@@ -534,7 +543,7 @@ MI_INFO *mi_open(const char *name, int m
my_errno=EACCES; /* Can't open in write mode */
goto err;
}
- if (mi_open_datafile(&info, share, old_info->dfile))
+ if (mi_open_datafile(&info, share, name, old_info->dfile))
goto err;
errpos=5;
have_rtree= old_info->rtree_recursion_state != NULL;
@@ -1191,12 +1200,30 @@ The argument file_to_dup is here for the
exist a dup()-like call that would give us two different file descriptors.
*************************************************************************/
-int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup __attribute__((unused)))
+int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *org_name,
+ File file_to_dup __attribute__((unused)))
{
+ char *data_name= share->data_file_name;
+ char real_data_name[FN_REFLEN];
+
+ if (org_name)
+ {
+ fn_format(real_data_name,org_name,"",MI_NAME_DEXT,4);
+ if (my_is_symlink(real_data_name))
+ {
+ if (my_realpath(real_data_name, real_data_name, MYF(0)) ||
+ (*myisam_test_invalid_symlink)(real_data_name))
+ {
+ my_errno= HA_WRONG_CREATE_OPTION;
+ return 1;
+ }
+ data_name= real_data_name;
+ }
+ }
#ifdef USE_RAID
if (share->base.raid_type)
{
- info->dfile=my_raid_open(share->data_file_name,
+ info->dfile=my_raid_open(data_name,
share->mode | O_SHARE,
share->base.raid_type,
share->base.raid_chunks,
@@ -1205,8 +1232,7 @@ int mi_open_datafile(MI_INFO *info, MYIS
}
else
#endif
- info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
- MYF(MY_WME));
+ info->dfile=my_open(data_name, share->mode | O_SHARE, MYF(MY_WME));
return info->dfile >= 0 ? 0 : 1;
}
=== modified file 'myisam/mi_static.c'
--- a/myisam/mi_static.c 2006-12-31 00:02:27 +0000
+++ b/myisam/mi_static.c 2008-08-26 08:32:43 +0000
@@ -41,6 +41,15 @@ my_off_t myisam_max_temp_length= MAX_FIL
ulong myisam_bulk_insert_tree_size=8192*1024;
ulong myisam_data_pointer_size=4;
+
+static int always_valid(const char *filename __attribute__((unused)))
+{
+ return 0;
+}
+
+int (*myisam_test_invalid_symlink)(const char *filename)= always_valid;
+
+
/*
read_vec[] is used for converting between P_READ_KEY.. and SEARCH_
Position is , == , >= , <= , > , <
=== modified file 'myisam/myisamchk.c'
--- a/myisam/myisamchk.c 2007-11-14 10:38:26 +0000
+++ b/myisam/myisamchk.c 2008-08-22 12:31:53 +0000
@@ -1039,7 +1039,7 @@ static int myisamchk(MI_CHECK *param, my
error|=change_to_newfile(filename,MI_NAME_DEXT,DATA_TMP_EXT,
raid_chunks,
MYF(0));
- if (mi_open_datafile(info,info->s, -1))
+ if (mi_open_datafile(info,info->s, NULL, -1))
error=1;
param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */
param->read_cache.file=info->dfile;
=== modified file 'myisam/myisamdef.h'
--- a/myisam/myisamdef.h 2007-04-18 11:22:23 +0000
+++ b/myisam/myisamdef.h 2008-08-22 12:31:53 +0000
@@ -739,7 +739,9 @@ void mi_disable_non_unique_index(MI_INFO
extern MI_INFO *test_if_reopen(char *filename);
my_bool check_table_is_closed(const char *name, const char *where);
-int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
+int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *orn_name,
+ File file_to_dup);
+
int mi_open_keyfile(MYISAM_SHARE *share);
void mi_setup_functions(register MYISAM_SHARE *share);
=== modified file 'myisam/rt_index.c'
--- a/myisam/rt_index.c 2007-10-05 10:41:56 +0000
+++ b/myisam/rt_index.c 2008-08-26 13:51:06 +0000
@@ -389,7 +389,7 @@ int rtree_get_first(MI_INFO *info, uint
info->rtree_recursion_depth = -1;
info->buff_used = 1;
- return rtree_get_req(info, &keyinfo[keynr], key_length, root, 0);
+ return rtree_get_req(info, keyinfo, key_length, root, 0);
}
@@ -436,7 +436,7 @@ int rtree_get_next(MI_INFO *info, uint k
return -1;
}
- return rtree_get_req(info, &keyinfo[keynr], key_length, root, 0);
+ return rtree_get_req(info, keyinfo, key_length, root, 0);
}
}
=== modified file 'mysql-test/r/group_min_max.result'
--- a/mysql-test/r/group_min_max.result 2008-08-19 10:36:24 +0000
+++ b/mysql-test/r/group_min_max.result 2008-08-27 13:03:17 +0000
@@ -2353,3 +2353,79 @@ a MIN(b) MAX(b) AVG(b)
2 1 3 2.0000
1 1 3 2.0000
DROP TABLE t1;
+create table t1 (a int, b int, primary key (a,b), key `index` (a,b)) engine=MyISAM;
+insert into t1 (a,b) values
+(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),
+(0,7),(0,8),(0,9),(0,10),(0,11),(0,12),(0,13),
+(1,0),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),
+(1,7),(1,8),(1,9),(1,10),(1,11),(1,12),(1,13),
+(2,0),(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),
+(2,7),(2,8),(2,9),(2,10),(2,11),(2,12),(2,13),
+(3,0),(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),
+(3,7),(3,8),(3,9),(3,10),(3,11),(3,12),(3,13);
+insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a;
+select * from t1;
+a b
+0 0
+0 1
+0 2
+0 3
+0 4
+0 5
+0 6
+0 7
+0 8
+0 9
+0 10
+0 11
+0 12
+0 13
+0 14
+1 0
+1 1
+1 2
+1 3
+1 4
+1 5
+1 6
+1 7
+1 8
+1 9
+1 10
+1 11
+1 12
+1 13
+2 0
+2 1
+2 2
+2 3
+2 4
+2 5
+2 6
+2 7
+2 8
+2 9
+2 10
+2 11
+2 12
+2 13
+3 0
+3 1
+3 2
+3 3
+3 4
+3 5
+3 6
+3 7
+3 8
+3 9
+3 10
+3 11
+3 12
+3 13
+explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,index PRIMARY 4 NULL 3 Using where; Using index for group-by; Using temporary
+Warnings:
+Note 1003 select sql_buffer_result `test`.`t1`.`a` AS `a`,(max(`test`.`t1`.`b`) + 1) AS `max(b)+1` from `test`.`t1` where (`test`.`t1`.`a` = 0) group by `test`.`t1`.`a`
+drop table t1;
=== modified file 'mysql-test/r/myisam.result'
--- a/mysql-test/r/myisam.result 2008-05-06 16:43:46 +0000
+++ b/mysql-test/r/myisam.result 2008-08-26 13:48:50 +0000
@@ -1861,4 +1861,26 @@ id ref
3 2
4 5
DROP TABLE t1, t2;
+CREATE TABLE t1 (a INT) ENGINE=MyISAM CHECKSUM=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES (0);
+UPDATE t1 SET a=1;
+SELECT a FROM t1;
+a
+1
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+INSERT INTO t1 VALUES (0), (5), (4), (2);
+UPDATE t1 SET a=2;
+SELECT a FROM t1;
+a
+2
+2
+2
+2
+2
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
End of 5.0 tests
=== modified file 'mysql-test/r/symlink.result'
--- a/mysql-test/r/symlink.result 2008-03-03 11:02:34 +0000
+++ b/mysql-test/r/symlink.result 2008-08-26 09:21:07 +0000
@@ -57,8 +57,6 @@ t9 CREATE TABLE `t9` (
Got one of the listed errors
Got one of the listed errors
Got one of the listed errors
-Got one of the listed errors
-Got one of the listed errors
alter table t9 rename mysqltest.t9;
select count(*) from mysqltest.t9;
count(*)
=== modified file 'mysql-test/r/type_bit.result'
--- a/mysql-test/r/type_bit.result 2007-12-02 00:48:43 +0000
+++ b/mysql-test/r/type_bit.result 2008-08-27 21:10:37 +0000
@@ -684,4 +684,28 @@ SELECT 1 FROM t1 GROUP BY a;
1
1
DROP TABLE t1;
+CREATE TABLE t1 (b BIT NOT NULL, i2 INTEGER NOT NULL, s VARCHAR(255) NOT NULL);
+INSERT INTO t1 VALUES(0x01,100,''), (0x00,300,''), (0x01,200,''), (0x00,100,'');
+SELECT HEX(b), i2 FROM t1 WHERE (i2>=100 AND i2<201) AND b=TRUE;
+HEX(b) i2
+1 100
+1 200
+CREATE TABLE t2 (b1 BIT NOT NULL, b2 BIT NOT NULL, i2 INTEGER NOT NULL,
+s VARCHAR(255) NOT NULL);
+INSERT INTO t2 VALUES (0x01,0x00,100,''), (0x00,0x01,300,''),
+(0x01,0x00,200,''), (0x00,0x01,100,'');
+SELECT HEX(b1), i2 FROM t2 WHERE (i2>=100 AND i2<201) AND b1=TRUE;
+HEX(b1) i2
+1 100
+1 200
+SELECT HEX(b2), i2 FROM t2 WHERE (i2>=100 AND i2<201) AND b2=FALSE;
+HEX(b2) i2
+0 100
+0 200
+SELECT HEX(b1), HEX(b2), i2 FROM t2
+WHERE (i2>=100 AND i2<201) AND b1=TRUE AND b2=FALSE;
+HEX(b1) HEX(b2) i2
+1 0 100
+1 0 200
+DROP TABLE t1, t2;
End of 5.0 tests
=== modified file 'mysql-test/r/udf.result'
--- a/mysql-test/r/udf.result 2007-11-27 15:16:52 +0000
+++ b/mysql-test/r/udf.result 2008-08-25 12:11:59 +0000
@@ -1,5 +1,7 @@
drop table if exists t1;
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
+Warnings:
+Warning 1105 plugin_dir was not specified
CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
ERROR HY000: Can't find function 'myfunc_nonexist' in library
@@ -197,6 +199,8 @@ DROP FUNCTION avgcost;
select * from mysql.func;
name ret dl type
CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
+Warnings:
+Warning 1105 plugin_dir was not specified
select IS_const(3);
IS_const(3)
const
@@ -206,6 +210,8 @@ name ret dl type
select is_const(3);
ERROR 42000: FUNCTION test.is_const does not exist
CREATE FUNCTION is_const RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
+Warnings:
+Warning 1105 plugin_dir was not specified
select
is_const(3) as const,
is_const(3.14) as const,
=== modified file 'mysql-test/t/group_min_max.test'
--- a/mysql-test/t/group_min_max.test 2008-08-19 10:36:24 +0000
+++ b/mysql-test/t/group_min_max.test 2008-08-27 13:03:17 +0000
@@ -916,3 +916,22 @@ SELECT a, MIN(b), MAX(b), AVG(b) FROM t1
SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC;
DROP TABLE t1;
+
+#
+# Bug#38195: Incorrect handling of aggregate functions when loose index scan is
+# used causes server crash.
+#
+create table t1 (a int, b int, primary key (a,b), key `index` (a,b)) engine=MyISAM;
+insert into t1 (a,b) values
+(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),
+ (0,7),(0,8),(0,9),(0,10),(0,11),(0,12),(0,13),
+(1,0),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),
+ (1,7),(1,8),(1,9),(1,10),(1,11),(1,12),(1,13),
+(2,0),(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),
+ (2,7),(2,8),(2,9),(2,10),(2,11),(2,12),(2,13),
+(3,0),(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),
+ (3,7),(3,8),(3,9),(3,10),(3,11),(3,12),(3,13);
+insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a;
+select * from t1;
+explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a;
+drop table t1;
=== modified file 'mysql-test/t/myisam.test'
--- a/mysql-test/t/myisam.test 2008-01-16 11:15:57 +0000
+++ b/mysql-test/t/myisam.test 2008-08-26 13:48:50 +0000
@@ -1210,4 +1210,19 @@ SELECT * FROM t1;
DROP TABLE t1, t2;
+
+#
+# Bug#37310: 'on update CURRENT_TIMESTAMP' option crashes the table
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM CHECKSUM=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES (0);
+UPDATE t1 SET a=1;
+SELECT a FROM t1;
+CHECK TABLE t1;
+INSERT INTO t1 VALUES (0), (5), (4), (2);
+UPDATE t1 SET a=2;
+SELECT a FROM t1;
+CHECK TABLE t1;
+DROP TABLE t1;
+
--echo End of 5.0 tests
=== modified file 'mysql-test/t/symlink.test'
--- a/mysql-test/t/symlink.test 2008-03-03 11:02:34 +0000
+++ b/mysql-test/t/symlink.test 2008-08-26 09:21:07 +0000
@@ -71,8 +71,6 @@ drop table t1;
SHOW CREATE TABLE t9;
disable_query_log;
---error 1103,1103
-create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam data directory="tmp";
# Check that we cannot link over a table from another database.
@@ -81,8 +79,9 @@ create database mysqltest;
--error 1,1
create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="/this-dir-does-not-exist";
---error 1103,1103
-create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path";
+# temporarily disabled as it returns different result in the embedded server
+# --error 1210, 1210
+# create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path";
# Should fail becasue the file t9.MYI already exist in 'run'
--error 1,1,1105
@@ -230,6 +229,7 @@ SET SESSION keep_files_on_create = TRUE;
EOF
--disable_abort_on_error
--error 1
+--replace_result $MYSQLTEST_VARDIR . master-data/ ''
CREATE TABLE t1 (a INT) ENGINE MYISAM;
--error 0,1
--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYD;
=== modified file 'mysql-test/t/type_bit.test'
--- a/mysql-test/t/type_bit.test 2007-11-21 18:56:42 +0000
+++ b/mysql-test/t/type_bit.test 2008-08-27 21:10:37 +0000
@@ -333,4 +333,23 @@ SELECT 1 FROM t1 GROUP BY a;
DROP TABLE t1;
+#
+# Bug#37799 SELECT with a BIT column in WHERE clause returns unexpected result
+#
+
+CREATE TABLE t1 (b BIT NOT NULL, i2 INTEGER NOT NULL, s VARCHAR(255) NOT NULL);
+INSERT INTO t1 VALUES(0x01,100,''), (0x00,300,''), (0x01,200,''), (0x00,100,'');
+SELECT HEX(b), i2 FROM t1 WHERE (i2>=100 AND i2<201) AND b=TRUE;
+
+CREATE TABLE t2 (b1 BIT NOT NULL, b2 BIT NOT NULL, i2 INTEGER NOT NULL,
+ s VARCHAR(255) NOT NULL);
+INSERT INTO t2 VALUES (0x01,0x00,100,''), (0x00,0x01,300,''),
+ (0x01,0x00,200,''), (0x00,0x01,100,'');
+SELECT HEX(b1), i2 FROM t2 WHERE (i2>=100 AND i2<201) AND b1=TRUE;
+SELECT HEX(b2), i2 FROM t2 WHERE (i2>=100 AND i2<201) AND b2=FALSE;
+SELECT HEX(b1), HEX(b2), i2 FROM t2
+ WHERE (i2>=100 AND i2<201) AND b1=TRUE AND b2=FALSE;
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
=== modified file 'mysys/my_symlink.c'
--- a/mysys/my_symlink.c 2006-12-23 19:17:15 +0000
+++ b/mysys/my_symlink.c 2008-08-26 08:32:43 +0000
@@ -106,38 +106,47 @@ int my_symlink(const char *content, cons
#define BUFF_LEN FN_LEN
#endif
+
+int my_is_symlink(const char *filename __attribute__((unused)))
+{
+#if defined (HAVE_LSTAT) && defined (S_ISLNK)
+ struct stat stat_buff;
+ return !lstat(filename, &stat_buff) && S_ISLNK(stat_buff.st_mode);
+#elif defined (_WIN32)
+ DWORD dwAttr = GetFileAttributes(filename);
+ return (dwAttr != INVALID_FILE_ATTRIBUTES) &&
+ (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT);
+#else /* No symlinks */
+ return 0;
+#endif
+}
+
+
int my_realpath(char *to, const char *filename,
myf MyFlags __attribute__((unused)))
{
#if defined(HAVE_REALPATH) && !defined(HAVE_purify) && !defined(HAVE_BROKEN_REALPATH)
int result=0;
char buff[BUFF_LEN];
- struct stat stat_buff;
+ char *ptr;
DBUG_ENTER("my_realpath");
- if (!(MyFlags & MY_RESOLVE_LINK) ||
- (!lstat(filename,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
- {
- char *ptr;
- DBUG_PRINT("info",("executing realpath"));
- if ((ptr=realpath(filename,buff)))
- {
+ DBUG_PRINT("info",("executing realpath"));
+ if ((ptr=realpath(filename,buff)))
strmake(to,ptr,FN_REFLEN-1);
- }
- else
- {
- /*
- Realpath didn't work; Use my_load_path() which is a poor substitute
- original name but will at least be able to resolve paths that starts
- with '.'.
- */
- DBUG_PRINT("error",("realpath failed with errno: %d", errno));
- my_errno=errno;
- if (MyFlags & MY_WME)
- my_error(EE_REALPATH, MYF(0), filename, my_errno);
- my_load_path(to, filename, NullS);
- result= -1;
- }
+ else
+ {
+ /*
+ Realpath didn't work; Use my_load_path() which is a poor substitute
+ original name but will at least be able to resolve paths that starts
+ with '.'.
+ */
+ DBUG_PRINT("error",("realpath failed with errno: %d", errno));
+ my_errno=errno;
+ if (MyFlags & MY_WME)
+ my_error(EE_REALPATH, MYF(0), filename, my_errno);
+ my_load_path(to, filename, NullS);
+ result= -1;
}
DBUG_RETURN(result);
#else
=== modified file 'mysys/thr_lock.c'
--- a/mysys/thr_lock.c 2007-08-05 09:17:07 +0000
+++ b/mysys/thr_lock.c 2008-08-25 13:18:52 +0000
@@ -333,10 +333,10 @@ void thr_lock_init(THR_LOCK *lock)
void thr_lock_delete(THR_LOCK *lock)
{
DBUG_ENTER("thr_lock_delete");
- VOID(pthread_mutex_destroy(&lock->mutex));
pthread_mutex_lock(&THR_LOCK_lock);
thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list);
pthread_mutex_unlock(&THR_LOCK_lock);
+ pthread_mutex_destroy(&lock->mutex);
DBUG_VOID_RETURN;
}
=== modified file 'sql/field.h'
--- a/sql/field.h 2008-08-11 16:10:00 +0000
+++ b/sql/field.h 2008-08-27 21:10:37 +0000
@@ -138,7 +138,7 @@ public:
virtual bool eq(Field *field)
{
return (ptr == field->ptr && null_ptr == field->null_ptr &&
- null_bit == field->null_bit);
+ null_bit == field->null_bit && field->type() == type());
}
virtual bool eq_def(Field *field);
@@ -1489,7 +1489,6 @@ public:
bool eq(Field *field)
{
return (Field::eq(field) &&
- field->type() == type() &&
bit_ptr == ((Field_bit *)field)->bit_ptr &&
bit_ofs == ((Field_bit *)field)->bit_ofs);
}
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2008-07-15 14:13:21 +0000
+++ b/sql/mysql_priv.h 2008-08-26 08:32:43 +0000
@@ -1264,6 +1264,7 @@ extern char *mysql_data_home,server_vers
mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
mysql_unpacked_real_data_home[],
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
+extern int mysql_unpacked_real_data_home_len;
#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list))
extern MY_TMPDIR mysql_tmpdir_list;
extern const char *command_name[];
@@ -1342,6 +1343,9 @@ extern char *default_tz_name;
extern my_bool opt_large_pages;
extern uint opt_large_page_size;
+extern char *opt_plugin_dir_ptr;
+extern char opt_plugin_dir[FN_REFLEN];
+
extern MYSQL_LOG mysql_log,mysql_slow_log,mysql_bin_log;
extern FILE *bootstrap_file;
extern int bootstrap_error;
@@ -1764,6 +1768,8 @@ inline void kill_delayed_threads(void) {
#define check_stack_overrun(A, B, C) 0
#endif
+extern "C" int test_if_data_home_dir(const char *dir);
+
#endif /* MYSQL_CLIENT */
#endif
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2008-06-03 10:12:37 +0000
+++ b/sql/mysqld.cc 2008-08-26 08:32:43 +0000
@@ -324,6 +324,9 @@ arg_cmp_func Arg_comparator::comparator_
/* static variables */
+char opt_plugin_dir[FN_REFLEN];
+char *opt_plugin_dir_ptr;
+
static bool lower_case_table_names_used= 0;
static bool volatile select_thread_in_use, signal_thread_in_use;
static bool volatile ready_to_exit;
@@ -477,6 +480,7 @@ char mysql_real_data_home[FN_REFLEN],
*opt_init_file, *opt_tc_log_file,
mysql_unpacked_real_data_home[FN_REFLEN],
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
+int mysql_unpacked_real_data_home_len;
char *mysql_data_home= mysql_real_data_home;
const key_map key_map_empty(0);
key_map key_map_full(0); // Will be initialized later
@@ -4984,6 +4988,7 @@ enum options_mysqld
OPT_OLD_STYLE_USER_LIMITS,
OPT_LOG_SLOW_ADMIN_STATEMENTS,
OPT_TABLE_LOCK_WAIT_TIMEOUT,
+ OPT_PLUGIN_DIR,
OPT_PORT_OPEN_TIMEOUT,
OPT_MERGE,
OPT_INNODB_ROLLBACK_ON_TIMEOUT,
@@ -6216,6 +6221,10 @@ The minimum value for this variable is 4
(gptr*) &global_system_variables.optimizer_search_depth,
(gptr*) &max_system_variables.optimizer_search_depth,
0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR,
+ "Directory for plugins.",
+ (gptr*) &opt_plugin_dir_ptr, (gptr*) &opt_plugin_dir_ptr, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
"The size of the buffer that is allocated when preloading indexes",
(gptr*) &global_system_variables.preload_buff_size,
@@ -6696,6 +6705,7 @@ static void mysql_init_variables(void)
/* Things reset to zero */
opt_skip_slave_start= opt_reckless_slave = 0;
mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
+ myisam_test_invalid_symlink= test_if_data_home_dir;
opt_log= opt_slow_log= 0;
opt_update_log= 0;
opt_bin_log= 0;
@@ -7746,13 +7756,19 @@ static void fix_paths(void)
pos[1]= 0;
}
convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
- (void) fn_format(buff, mysql_real_data_home, "", "",
- (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
- (void) unpack_dirname(mysql_unpacked_real_data_home, buff);
+ my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
+ mysql_unpacked_real_data_home_len= strlen(mysql_unpacked_real_data_home);
+ if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
+ --mysql_unpacked_real_data_home_len;
+
+
convert_dirname(language,language,NullS);
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
(void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
+ (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
+ "", "");
+ opt_plugin_dir_ptr= opt_plugin_dir;
char *sharedir=get_relative_path(SHAREDIR);
if (test_if_hard_path(sharedir))
=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc 2008-07-23 11:25:00 +0000
+++ b/sql/opt_range.cc 2008-08-25 17:02:54 +0000
@@ -7103,6 +7103,13 @@ QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUI
used_key_parts (used_key_parts_arg)
{
QUICK_RANGE *r;
+ /*
+ Use default MRR implementation for reverse scans. No table engine
+ currently can do an MRR scan with output in reverse index order.
+ */
+ multi_range_length= 0;
+ multi_range= NULL;
+ multi_range_buff= NULL;
QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
QUICK_RANGE **end_range= pr + ranges.elements;
=== modified file 'sql/opt_range.h'
--- a/sql/opt_range.h 2008-07-23 11:25:00 +0000
+++ b/sql/opt_range.h 2008-08-25 17:02:54 +0000
@@ -329,14 +329,7 @@ public:
void dbug_dump(int indent, bool verbose);
#endif
private:
- /* Used only by QUICK_SELECT_DESC */
- QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I()
- {
- bcopy(&org, this, sizeof(*this));
- multi_range_length= 0;
- multi_range= NULL;
- multi_range_buff= NULL;
- }
+ /* Default copy ctor used by QUICK_SELECT_DESC */
};
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2008-07-16 22:29:22 +0000
+++ b/sql/set_var.cc 2008-08-25 12:11:59 +0000
@@ -1026,6 +1026,7 @@ struct show_var_st init_vars[]= {
{sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth,
SHOW_SYS},
{"pid_file", (char*) pidfile_name, SHOW_CHAR},
+ {"plugin_dir", (char*) opt_plugin_dir, SHOW_CHAR},
{"port", (char*) &mysqld_port, SHOW_INT},
{sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS},
{"protocol_version", (char*) &protocol_version, SHOW_INT},
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2008-07-29 13:15:04 +0000
+++ b/sql/sql_parse.cc 2008-08-26 08:32:43 +0000
@@ -76,7 +76,6 @@ static void remove_escape(char *name);
static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
-static bool test_if_data_home_dir(const char *dir);
const char *any_db="*any*"; // Special symbol for check_access
@@ -3044,13 +3043,13 @@ mysql_execute_command(THD *thd)
if (test_if_data_home_dir(lex->create_info.data_file_name))
{
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY");
+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECTORY");
res= -1;
break;
}
if (test_if_data_home_dir(lex->create_info.index_file_name))
{
- my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY");
+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECTORY");
res= -1;
break;
}
@@ -7946,10 +7945,12 @@ bool check_string_length(LEX_STRING *str
1 error
*/
-static bool test_if_data_home_dir(const char *dir)
+C_MODE_START
+
+int test_if_data_home_dir(const char *dir)
{
- char path[FN_REFLEN], conv_path[FN_REFLEN];
- uint dir_len, home_dir_len= strlen(mysql_unpacked_real_data_home);
+ char path[FN_REFLEN];
+ int dir_len;
DBUG_ENTER("test_if_data_home_dir");
if (!dir)
@@ -7957,21 +7958,27 @@ static bool test_if_data_home_dir(const
(void) fn_format(path, dir, "", "",
(MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
- dir_len= unpack_dirname(conv_path, dir);
-
- if (home_dir_len <= dir_len)
+ dir_len= strlen(path);
+ if (mysql_unpacked_real_data_home_len<= dir_len)
{
+ if (dir_len > mysql_unpacked_real_data_home_len &&
+ path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
+ DBUG_RETURN(0);
+
if (lower_case_file_system)
{
- if (!my_strnncoll(default_charset_info, (const uchar*) conv_path,
- home_dir_len,
+ if (!my_strnncoll(default_charset_info, (const uchar*) path,
+ mysql_unpacked_real_data_home_len,
(const uchar*) mysql_unpacked_real_data_home,
- home_dir_len))
+ mysql_unpacked_real_data_home_len))
DBUG_RETURN(1);
}
- else if (!memcmp(conv_path, mysql_unpacked_real_data_home, home_dir_len))
+ else if (!memcmp(path, mysql_unpacked_real_data_home,
+ mysql_unpacked_real_data_home_len))
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
+C_MODE_END
+
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2008-08-19 10:36:24 +0000
+++ b/sql/sql_select.cc 2008-08-27 13:03:17 +0000
@@ -1724,7 +1724,8 @@ JOIN::exec()
if (!items1)
{
items1= items0 + all_fields.elements;
- if (sort_and_group || curr_tmp_table->group)
+ if (sort_and_group || curr_tmp_table->group ||
+ tmp_table_param.precomputed_group_by)
{
if (change_to_use_tmp_fields(thd, items1,
tmp_fields_list1, tmp_all_fields1,
@@ -9259,6 +9260,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARA
MI_COLUMNDEF *recinfo;
uint total_uneven_bit_length= 0;
bool force_copy_fields= param->force_copy_fields;
+ /* Treat sum functions as normal ones when loose index scan is used. */
+ save_sum_fields|= param->precomputed_group_by;
DBUG_ENTER("create_tmp_table");
DBUG_PRINT("enter",("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d",
(int) distinct, (int) save_sum_fields,
=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc 2008-07-15 14:13:21 +0000
+++ b/sql/sql_udf.cc 2008-08-25 12:11:59 +0000
@@ -214,7 +214,17 @@ void udf_init()
void *dl = find_udf_dl(tmp->dl);
if (dl == NULL)
{
- if (!(dl = dlopen(tmp->dl, RTLD_NOW)))
+ char dlpath[FN_REFLEN];
+ if (*opt_plugin_dir)
+ strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl,
+ NullS);
+ else
+ {
+ strxnmov(dlpath, sizeof(dlpath)-1, tmp->dl, NullS);
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "plugin_dir was not specified");
+ }
+ if (!(dl = dlopen(dlpath, RTLD_NOW)))
{
/* Print warning to log */
sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl,errno,dlerror());
@@ -443,8 +453,18 @@ int mysql_create_function(THD *thd,udf_f
}
if (!(dl = find_udf_dl(udf->dl)))
{
- DBUG_PRINT("info", ("Calling dlopen, udf->dl: %s", udf->dl));
- if (!(dl = dlopen(udf->dl, RTLD_NOW)))
+ char dlpath[FN_REFLEN];
+ if (*opt_plugin_dir)
+ strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", udf->dl,
+ NullS);
+ else
+ {
+ strxnmov(dlpath, sizeof(dlpath)-1, udf->dl, NullS);
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "plugin_dir was not specified");
+ }
+ DBUG_PRINT("info", ("Calling dlopen, udf->dl: %s", dlpath));
+ if (!(dl = dlopen(dlpath, RTLD_NOW)))
{
DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)",
udf->dl,errno,dlerror()));
=== modified file 'sql/unireg.h'
--- a/sql/unireg.h 2008-04-10 00:34:38 +0000
+++ b/sql/unireg.h 2008-08-25 12:11:59 +0000
@@ -35,6 +35,9 @@
#ifndef SHAREDIR
#define SHAREDIR "share/"
#endif
+#ifndef PLUGINDIR
+#define PLUGINDIR "lib/plugin"
+#endif
#define ER(X) errmesg[(X) - ER_ERROR_FIRST]
#define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code")
| Thread |
|---|
| • bzr push into mysql-5.0 branch (joerg:2652 to 2653) | Joerg Bruehe | 10 Sep |