summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql_upgrade.c11
-rw-r--r--client/mysqltest.c3
-rw-r--r--dbug/dbug.c2
-rw-r--r--include/my_global.h8
-rwxr-xr-xmysql-test/mysql-test-run.pl13
-rw-r--r--mysql-test/r/ctype_gbk.result7
-rw-r--r--mysql-test/r/func_gconcat.result26
-rw-r--r--mysql-test/r/subselect.result7
-rw-r--r--mysql-test/r/subselect3.result9
-rw-r--r--mysql-test/r/type_decimal.result7
-rw-r--r--mysql-test/t/ctype_gbk.test14
-rw-r--r--mysql-test/t/func_gconcat.test36
-rw-r--r--mysql-test/t/subselect.test12
-rw-r--r--mysql-test/t/subselect3.test13
-rw-r--r--mysql-test/t/type_decimal.test8
-rw-r--r--mysys/thr_alarm.c3
-rw-r--r--sql/item.cc11
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/my_decimal.h13
-rw-r--r--sql/sql_select.cc1
-rw-r--r--strings/ctype-big5.c6
-rw-r--r--strings/ctype-gbk.c6
22 files changed, 199 insertions, 19 deletions
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 02829cd2178..ded9d465d3a 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -40,6 +40,8 @@ static DYNAMIC_STRING ds_args;
static char *opt_password= 0;
static my_bool tty_password= 0;
+static char opt_tmpdir[FN_REFLEN];
+
#ifndef DBUG_OFF
static char *default_dbug_option= (char*) "d:t:O,/tmp/mysql_upgrade.trace";
#endif
@@ -105,6 +107,8 @@ static struct my_option my_long_options[]=
#endif
{"socket", 'S', "Socket file to use for connection.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"tmpdir", 't', "Directory for temporary files",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"user", 'u', "User for login if not current user.", (gptr*) &opt_user,
(gptr*) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include <sslopt-longopts.h>
@@ -229,6 +233,11 @@ get_one_option(int optid, const struct my_option *opt,
}
break;
+ case 't':
+ strnmov(opt_tmpdir, argument, sizeof(opt_tmpdir));
+ add_option= FALSE;
+ break;
+
case 'b': /* --basedir */
case 'v': /* --verbose */
case 'd': /* --datadir */
@@ -449,7 +458,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
char query_file_path[FN_REFLEN];
DBUG_ENTER("run_query");
DBUG_PRINT("enter", ("query: %s", query));
- if ((fd= create_temp_file(query_file_path, NULL,
+ if ((fd= create_temp_file(query_file_path, opt_tmpdir,
"sql", O_CREAT | O_SHARE | O_RDWR,
MYF(MY_WME))) < 0)
die("Failed to create temporary file for defaults");
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 1d85e777e48..9c7c4d62f6f 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1536,7 +1536,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
DBUG_ENTER("dyn_string_cmp");
DBUG_PRINT("enter", ("fname: %s", fname));
- if ((fd= create_temp_file(temp_file_path, NULL,
+ if ((fd= create_temp_file(temp_file_path, TMPDIR,
"tmp", O_CREAT | O_SHARE | O_RDWR,
MYF(MY_WME))) < 0)
die("Failed to create temporary file for ds");
@@ -5464,6 +5464,7 @@ void init_win_path_patterns()
const char* paths[] = { "$MYSQL_TEST_DIR",
"$MYSQL_TMP_DIR",
"$MYSQLTEST_VARDIR",
+ "$MASTER_MYSOCK",
"./test/" };
int num_paths= sizeof(paths)/sizeof(char*);
int i;
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 09515dc329c..baf080f5e27 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -493,7 +493,7 @@ static void DbugParse(CODE_STATE *cs, const char *control)
}
end= DbugStrTok(control);
- while (1)
+ while (control < end)
{
int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0;
if (sign) control++;
diff --git a/include/my_global.h b/include/my_global.h
index b0a26e67d9b..e474b620d27 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -533,8 +533,12 @@ C_MODE_END
#undef DBUG_OFF
#endif
-#if defined(_lint) && !defined(DBUG_OFF)
-#define DBUG_OFF
+/* We might be forced to turn debug off, if not turned off already */
+#if (defined(FORCE_DBUG_OFF) || defined(_lint)) && !defined(DBUG_OFF)
+# define DBUG_OFF
+# ifdef DBUG_ON
+# undef DBUG_ON
+# endif
#endif
#include <my_dbug.h>
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 86e41c19284..9b16471cda1 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1367,7 +1367,15 @@ sub datadir_list_setup () {
sub collect_mysqld_features () {
my $found_variable_list_start= 0;
- my $tmpdir= tempdir(CLEANUP => 0); # Directory removed by this function
+ my $tmpdir;
+ if ( $opt_tmpdir ) {
+ # Use the requested tmpdir
+ mkpath($opt_tmpdir) if (! -d $opt_tmpdir);
+ $tmpdir= $opt_tmpdir;
+ }
+ else {
+ $tmpdir= tempdir(CLEANUP => 0); # Directory removed by this function
+ }
#
# Execute "mysqld --no-defaults --help --verbose" to get a
@@ -1428,7 +1436,7 @@ sub collect_mysqld_features () {
}
}
}
- rmtree($tmpdir);
+ rmtree($tmpdir) if (!$opt_tmpdir);
mtr_error("Could not find version of MySQL") unless $mysql_version_id;
mtr_error("Could not find variabes list") unless $found_variable_list_start;
@@ -1737,6 +1745,7 @@ sub mysql_upgrade_arguments()
mtr_add_arg($args, "--socket=$master->[0]->{'path_sock'}");
mtr_add_arg($args, "--datadir=$master->[0]->{'path_myddir'}");
mtr_add_arg($args, "--basedir=$glob_basedir");
+ mtr_add_arg($args, "--tmpdir=$opt_tmpdir");
if ( $opt_debug )
{
diff --git a/mysql-test/r/ctype_gbk.result b/mysql-test/r/ctype_gbk.result
index 6066246a2ef..1b425134095 100644
--- a/mysql-test/r/ctype_gbk.result
+++ b/mysql-test/r/ctype_gbk.result
@@ -247,4 +247,11 @@ t1 CREATE TABLE `t1` (
`c2` text NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=gbk
drop table t1;
+CREATE TABLE t1(a MEDIUMTEXT CHARACTER SET gbk,
+b MEDIUMTEXT CHARACTER SET big5);
+INSERT INTO t1 VALUES
+(REPEAT(0x1125,200000), REPEAT(0x1125,200000)), ('', ''), ('', '');
+SELECT a FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll;
+SELECT b FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll;
+DROP TABLES t1;
End of 5.0 tests
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 77d11831842..4dddc35e8a8 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -946,4 +946,30 @@ GROUP BY 1
d1
NULL
DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES(1);
+SELECT GROUP_CONCAT(DISTINCT t2.a) FROM t1 LEFT JOIN t2 ON t2.a = t1.a GROUP BY t1.a;
+GROUP_CONCAT(DISTINCT t2.a)
+NULL
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a INT, KEY(a));
+CREATE TABLE t2 (b INT);
+INSERT INTO t1 VALUES (NULL), (8), (2);
+INSERT INTO t2 VALUES (4), (10);
+SELECT 1 FROM t1 WHERE t1.a NOT IN
+(
+SELECT GROUP_CONCAT(DISTINCT t1.a)
+FROM t1 WHERE t1.a IN
+(
+SELECT b FROM t2
+)
+AND NOT t1.a >= (SELECT t1.a FROM t1 LIMIT 1)
+GROUP BY t1.a
+);
+1
+1
+1
+1
+DROP TABLE t1, t2;
End of 5.0 tests
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 2de2589fc92..e56c2f07d80 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -4374,4 +4374,11 @@ a4 f3 a6
1 NULL NULL
2 NULL NULL
DROP TABLE t1, t2, t3, t4;
+create table t1 (a float(5,4) zerofill);
+create table t2 (a float(5,4),b float(2,0));
+select t1.a from t1 where
+t1.a= (select b from t2 limit 1) and not
+t1.a= (select a from t2 limit 1) ;
+a
+drop table t1, t2;
End of 5.0 tests.
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index c194ba33756..5221fa09744 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -770,4 +770,13 @@ SELECT ROW(1, 2) IN (SELECT t1.a, 2 FROM t2) FROM t1 GROUP BY t1.a;
ROW(1, 2) IN (SELECT t1.a, 2 FROM t2)
1
DROP TABLE t1, t2;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+CREATE TABLE t2 SELECT * FROM t1;
+SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
+1
+1
+1
+1
+DROP TABLE t1, t2;
End of 5.0 tests
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index 2afd42f702e..03fbc898cc5 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -946,4 +946,11 @@ SELECT ROUND(20061108085411.000002);
ROUND(20061108085411.000002)
20061108085411
DROP TABLE t1, t2, t3, t4, t5, t6;
+create table t1(`c` decimal(9,2));
+insert into t1 values (300),(201.11);
+select max(case 1 when 1 then c else null end) from t1 group by c;
+max(case 1 when 1 then c else null end)
+201.11
+300.00
+drop table t1;
End of 5.0 tests
diff --git a/mysql-test/t/ctype_gbk.test b/mysql-test/t/ctype_gbk.test
index 3ea696338dc..91fe50d89b9 100644
--- a/mysql-test/t/ctype_gbk.test
+++ b/mysql-test/t/ctype_gbk.test
@@ -53,4 +53,18 @@ alter table t1 change c1 c1 mediumtext character set gbk not null;
show create table t1;
drop table t1;
+#
+# Bug#35993: severe memory corruption and crash with multibyte conversion
+#
+
+CREATE TABLE t1(a MEDIUMTEXT CHARACTER SET gbk,
+ b MEDIUMTEXT CHARACTER SET big5);
+INSERT INTO t1 VALUES
+ (REPEAT(0x1125,200000), REPEAT(0x1125,200000)), ('', ''), ('', '');
+
+SELECT a FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll;
+SELECT b FROM t1 GROUP BY 1 LIMIT 1 INTO @nullll;
+
+DROP TABLES t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index 87632fbdbb8..816ac9c2959 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -657,4 +657,40 @@ SELECT s1.d1 FROM
) AS s1;
DROP TABLE t1;
+#
+# Bug #35298: GROUP_CONCAT with DISTINCT can crash the server
+#
+
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+
+INSERT INTO t1 VALUES(1);
+
+SELECT GROUP_CONCAT(DISTINCT t2.a) FROM t1 LEFT JOIN t2 ON t2.a = t1.a GROUP BY t1.a;
+
+DROP TABLE t1, t2;
+
+#
+# Bug #36024: group_concat distinct in subquery crash
+#
+
+CREATE TABLE t1 (a INT, KEY(a));
+CREATE TABLE t2 (b INT);
+
+INSERT INTO t1 VALUES (NULL), (8), (2);
+INSERT INTO t2 VALUES (4), (10);
+
+SELECT 1 FROM t1 WHERE t1.a NOT IN
+(
+ SELECT GROUP_CONCAT(DISTINCT t1.a)
+ FROM t1 WHERE t1.a IN
+ (
+ SELECT b FROM t2
+ )
+ AND NOT t1.a >= (SELECT t1.a FROM t1 LIMIT 1)
+ GROUP BY t1.a
+);
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index c5edd5414e3..527bd528f79 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -3259,5 +3259,17 @@ GROUP BY a4;
DROP TABLE t1, t2, t3, t4;
+#
+# BUG#36139 "float, zerofill, crash with subquery"
+#
+create table t1 (a float(5,4) zerofill);
+create table t2 (a float(5,4),b float(2,0));
+
+select t1.a from t1 where
+ t1.a= (select b from t2 limit 1) and not
+ t1.a= (select a from t2 limit 1) ;
+
+drop table t1, t2;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index cfbde8c29cd..d7bb1f7186a 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -605,4 +605,17 @@ SELECT ROW(1, 2) IN (SELECT t1.a, 2 FROM t2) FROM t1 GROUP BY t1.a;
DROP TABLE t1, t2;
+#
+# Bug #36005: crash in subselect with single row
+# (subselect_single_select_engine::exec)
+#
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+CREATE TABLE t2 SELECT * FROM t1;
+
+SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index 6841b3cdd68..8a81908296f 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -521,4 +521,12 @@ SELECT ROUND(20061108085411.000002);
DROP TABLE t1, t2, t3, t4, t5, t6;
+#
+# Bug#36023: Incorrect handling of zero length caused an assertion to fail.
+#
+create table t1(`c` decimal(9,2));
+insert into t1 values (300),(201.11);
+select max(case 1 when 1 then c else null end) from t1 group by c;
+drop table t1;
+
--echo End of 5.0 tests
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index d11883a4ea4..94ef309097a 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -14,8 +14,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* To avoid problems with alarms in debug code, we disable DBUG here */
-#undef DBUG_OFF
-#define DBUG_OFF
+#define FORCE_DBUG_OFF
#include <my_global.h>
#if defined(THREAD) && !defined(DONT_USE_THR_ALARM)
diff --git a/sql/item.cc b/sql/item.cc
index 553ba1b152c..9ff1f8c0084 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4156,9 +4156,14 @@ static void convert_zerofill_number_to_string(Item **item, Field_num *field)
String tmp(buff,sizeof(buff), field->charset()), *res;
res= (*item)->val_str(&tmp);
- field->prepend_zeros(res);
- pos= (char *) sql_strmake (res->ptr(), res->length());
- *item= new Item_string(pos, res->length(), field->charset());
+ if ((*item)->is_null())
+ *item= new Item_null();
+ else
+ {
+ field->prepend_zeros(res);
+ pos= (char *) sql_strmake (res->ptr(), res->length());
+ *item= new Item_string(pos, res->length(), field->charset());
+ }
}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 91f9889b03f..91320d6b56b 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -3222,7 +3222,7 @@ void Item_func_group_concat::clear()
no_appended= TRUE;
if (tree)
reset_tree(tree);
- if (distinct)
+ if (unique_filter)
unique_filter->reset();
/* No need to reset the table as we never call write_row */
}
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index c661579ea66..6a0d05921ec 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -164,14 +164,23 @@ inline int check_result_and_overflow(uint mask, int result, my_decimal *val)
inline uint my_decimal_length_to_precision(uint length, uint scale,
bool unsigned_flag)
{
- return (uint) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1));
+ /* Precision can't be negative thus ignore unsigned_flag when length is 0. */
+ DBUG_ASSERT(length || !scale);
+ return (uint) (length - (scale>0 ? 1:0) -
+ (unsigned_flag || !length ? 0:1));
}
inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale,
bool unsigned_flag)
{
+ /*
+ When precision is 0 it means that original length was also 0. Thus
+ unsigned_flag is ignored in this case.
+ */
+ DBUG_ASSERT(precision || !scale);
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
- return (uint32)(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1));
+ return (uint32)(precision + (scale>0 ? 1:0) +
+ (unsigned_flag || !precision ? 0:1));
}
inline
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 976d7322f56..11062998e6a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -832,6 +832,7 @@ JOIN::optimize()
"Impossible HAVING" : "Impossible WHERE"));
zero_result_cause= having_value == Item::COND_FALSE ?
"Impossible HAVING" : "Impossible WHERE";
+ tables= 0;
error= 0;
DBUG_RETURN(0);
}
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index 44b9951657d..c73247db404 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -307,15 +307,17 @@ static int my_strnxfrm_big5(CHARSET_INFO *cs __attribute__((unused)),
{
uint16 e;
uint dstlen= len;
+ uchar *dest_end= dest + dstlen;
len = srclen;
- while (len--)
+ while (len-- && dest < dest_end)
{
if ((len > 0) && isbig5code(*src, *(src+1)))
{
e = big5strokexfrm((uint16) big5code(*src, *(src+1)));
*dest++ = big5head(e);
- *dest++ = big5tail(e);
+ if (dest < dest_end)
+ *dest++ = big5tail(e);
src +=2;
len--;
} else
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index 8ac7d62c9da..d0ba33aa3cc 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -2668,15 +2668,17 @@ static int my_strnxfrm_gbk(CHARSET_INFO *cs __attribute__((unused)),
{
uint16 e;
uint dstlen= len;
+ uchar *dest_end= dest + dstlen;
len = srclen;
- while (len--)
+ while (len-- && dest < dest_end)
{
if ((len > 0) && isgbkcode(*src, *(src+1)))
{
e = gbksortorder((uint16) gbkcode(*src, *(src+1)));
*dest++ = gbkhead(e);
- *dest++ = gbktail(e);
+ if (dest < dest_end)
+ *dest++ = gbktail(e);
src+=2;
len--;
} else