diff options
-rw-r--r-- | client/mysql_upgrade.c | 11 | ||||
-rw-r--r-- | client/mysqltest.c | 3 | ||||
-rw-r--r-- | dbug/dbug.c | 2 | ||||
-rw-r--r-- | include/my_global.h | 8 | ||||
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 13 | ||||
-rw-r--r-- | mysql-test/r/ctype_gbk.result | 7 | ||||
-rw-r--r-- | mysql-test/r/func_gconcat.result | 26 | ||||
-rw-r--r-- | mysql-test/r/subselect.result | 7 | ||||
-rw-r--r-- | mysql-test/r/subselect3.result | 9 | ||||
-rw-r--r-- | mysql-test/r/type_decimal.result | 7 | ||||
-rw-r--r-- | mysql-test/t/ctype_gbk.test | 14 | ||||
-rw-r--r-- | mysql-test/t/func_gconcat.test | 36 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 12 | ||||
-rw-r--r-- | mysql-test/t/subselect3.test | 13 | ||||
-rw-r--r-- | mysql-test/t/type_decimal.test | 8 | ||||
-rw-r--r-- | mysys/thr_alarm.c | 3 | ||||
-rw-r--r-- | sql/item.cc | 11 | ||||
-rw-r--r-- | sql/item_sum.cc | 2 | ||||
-rw-r--r-- | sql/my_decimal.h | 13 | ||||
-rw-r--r-- | sql/sql_select.cc | 1 | ||||
-rw-r--r-- | strings/ctype-big5.c | 6 | ||||
-rw-r--r-- | strings/ctype-gbk.c | 6 |
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 |