diff options
37 files changed, 254 insertions, 98 deletions
@@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=46 +MYSQL_VERSION_PATCH=47 MYSQL_VERSION_EXTRA= diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c index 99da157f8c6..bc9969c9b66 100644 --- a/client/mysql_plugin.c +++ b/client/mysql_plugin.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -407,7 +407,7 @@ exit: static void usage(void) { PRINT_VERSION; - puts("Copyright (c) 2011, Oracle and/or its affiliates. " + puts("Copyright (c) 2011, 2015, Oracle and/or its affiliates. " "All rights reserved.\n"); puts("Enable or disable plugins."); printf("\nUsage: %s [options] <plugin> ENABLE|DISABLE\n\nOptions:\n", @@ -758,6 +758,11 @@ static int check_options(int argc, char **argv, char *operation) /* read the plugin config file and check for match against argument */ else { + if (strlen(argv[i]) + 4 + 1 > FN_REFLEN) + { + fprintf(stderr, "ERROR: argument is too long.\n"); + return 1; + } strcpy(plugin_name, argv[i]); strcpy(config_file, argv[i]); strcat(config_file, ".ini"); @@ -849,6 +854,7 @@ static int process_options(int argc, char *argv[], char *operation) if (opt_basedir[i-1] != FN_LIBCHAR || opt_basedir[i-1] != FN_LIBCHAR2) { char buff[FN_REFLEN]; + memset(buff, 0, sizeof(buff)); strncpy(buff, opt_basedir, sizeof(buff) - 1); #ifdef __WIN__ diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index d8ee8f0d911..0be8f91af59 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -1,6 +1,6 @@ /* Copyright (c) 2006, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, Monty Program Ab. + Copyright (c) 2010, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 37ede5cac30..267d847aa52 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,6 +1,6 @@ /* Copyright (c) 2001, 2011, Oracle and/or its affiliates. - Copyright (c) 2010, 2011, Monty Program Ab. + Copyright (c) 2010, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/client/mysqldump.c b/client/mysqldump.c index cfd38e019ba..b3a58abd88d 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, Monty Program Ab. + Copyright (c) 2010, 2015, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 5bcdd911cfd..b4514f5a678 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -1,6 +1,6 @@ /* - Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2010, 2012, Monty Program Ab + Copyright (c) 2000, 2015, Oracle and/or its affiliates. + Copyright (c) 2010, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -369,7 +369,7 @@ list_dbs(MYSQL *mysql,const char *wild) uint length, counter = 0; ulong rowcount = 0L; char tables[NAME_LEN+1], rows[NAME_LEN+1]; - char query[255]; + char query[NAME_LEN + 100]; MYSQL_FIELD *field; MYSQL_RES *result; MYSQL_ROW row= NULL, rrow; @@ -436,7 +436,8 @@ list_dbs(MYSQL *mysql,const char *wild) MYSQL_ROW trow; while ((trow = mysql_fetch_row(tresult))) { - sprintf(query,"SELECT COUNT(*) FROM `%s`",trow[0]); + my_snprintf(query, sizeof(query), + "SELECT COUNT(*) FROM `%s`", trow[0]); if (!(mysql_query(mysql,query))) { MYSQL_RES *rresult; @@ -492,7 +493,7 @@ list_tables(MYSQL *mysql,const char *db,const char *table) { const char *header; uint head_length, counter = 0; - char query[255], rows[NAME_LEN], fields[16]; + char query[NAME_LEN + 100], rows[NAME_LEN], fields[16]; MYSQL_FIELD *field; MYSQL_RES *result; MYSQL_ROW row, rrow; @@ -577,7 +578,8 @@ list_tables(MYSQL *mysql,const char *db,const char *table) if (opt_verbose > 1) { /* Print the count of rows for each table */ - sprintf(query,"SELECT COUNT(*) FROM `%s`",row[0]); + my_snprintf(query, sizeof(query), "SELECT COUNT(*) FROM `%s`", + row[0]); if (!(mysql_query(mysql,query))) { if ((rresult = mysql_store_result(mysql))) @@ -637,13 +639,15 @@ list_tables(MYSQL *mysql,const char *db,const char *table) static int list_table_status(MYSQL *mysql,const char *db,const char *wild) { - char query[1024],*end; + char query[NAME_LEN + 100]; + int len; MYSQL_RES *result; MYSQL_ROW row; - end=strxmov(query,"show table status from `",db,"`",NullS); - if (wild && wild[0]) - strxmov(end," like '",wild,"'",NullS); + len= sizeof(query); + len-= my_snprintf(query, len, "show table status from `%s`", db); + if (wild && wild[0] && len) + strxnmov(query + strlen(query), len, " like '", wild, "'", NullS); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot get status for db: %s, table: %s: %s\n", @@ -675,7 +679,8 @@ static int list_fields(MYSQL *mysql,const char *db,const char *table, const char *wild) { - char query[1024],*end; + char query[NAME_LEN + 100]; + int len; MYSQL_RES *result; MYSQL_ROW row; ulong UNINIT_VAR(rows); @@ -689,7 +694,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table, if (opt_count) { - sprintf(query,"select count(*) from `%s`", table); + my_snprintf(query, sizeof(query), "select count(*) from `%s`", table); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot get record count for db: %s, table: %s: %s\n", @@ -701,9 +706,11 @@ list_fields(MYSQL *mysql,const char *db,const char *table, mysql_free_result(result); } - end=strmov(strmov(strmov(query,"show /*!32332 FULL */ columns from `"),table),"`"); - if (wild && wild[0]) - strxmov(end," like '",wild,"'",NullS); + len= sizeof(query); + len-= my_snprintf(query, len, "show /*!32332 FULL */ columns from `%s`", + table); + if (wild && wild[0] && len) + strxnmov(query + strlen(query), len, " like '", wild, "'", NullS); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot list columns in db: %s, table: %s: %s\n", @@ -724,7 +731,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table, print_res_top(result); if (opt_show_keys) { - end=strmov(strmov(strmov(query,"show keys from `"),table),"`"); + my_snprintf(query, sizeof(query), "show keys from `%s`", table); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot list keys in db: %s, table: %s: %s\n", diff --git a/libmysql/conf_to_src.c b/libmysql/conf_to_src.c index a5a7d23db0b..0e92388c93c 100644 --- a/libmysql/conf_to_src.c +++ b/libmysql/conf_to_src.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -118,7 +118,7 @@ print_arrays_for(char *set) { FILE *f; - sprintf(buf, "%s.conf", set); + snprintf(buf, sizeof(buf), "%s.conf", set); if ((f = fopen(buf, "r")) == NULL) { fprintf(stderr, "%s: can't read conf file for charset %s\n", prog, set); diff --git a/mysql-test/r/events_1.result b/mysql-test/r/events_1.result index 475a190d73d..e03ccf51d8b 100644 --- a/mysql-test/r/events_1.result +++ b/mysql-test/r/events_1.result @@ -114,8 +114,7 @@ create table t_event3 (a int, b float); drop event if exists event3; Warnings: Note 1305 Event event3 does not exist -create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) -comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); +create event event3 on schedule every 50 + 10 minute starts date_add(curdate(), interval 5 minute) ends date_add(curdate(), interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); select count(*) from t_event3; count(*) 0 diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index b93c70f27c8..ad93bfcd462 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -551,7 +551,7 @@ MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) DROP TABLE t1; CREATE TABLE t1(a TEXT); SELECT GROUP_CONCAT(a) AS st FROM t1 HAVING MATCH(st) AGAINST('test' IN BOOLEAN MODE); -ERROR HY000: Incorrect arguments to AGAINST +ERROR HY000: Incorrect arguments to MATCH DROP TABLE t1; CREATE TABLE t1(a VARCHAR(64), FULLTEXT(a)); INSERT INTO t1 VALUES('awrd bwrd cwrd'),('awrd bwrd cwrd'),('awrd bwrd cwrd'); diff --git a/mysql-test/r/mysql_plugin.result b/mysql-test/r/mysql_plugin.result index 636b039047e..0bcb47e4a10 100644 --- a/mysql-test/r/mysql_plugin.result +++ b/mysql-test/r/mysql_plugin.result @@ -102,7 +102,7 @@ ERROR: Missing --plugin_dir option. # Show the help. # mysql_plugin Ver V.V.VV Distrib XX.XX.XX -Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. Enable or disable plugins. diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index 805ee82a3ac..5f81ee567f1 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -298,6 +298,13 @@ test Phase 4/4: Running 'mysql_fix_privilege_tables' OK # +# Bug #21489398: MYSQL_UPGRADE: FATAL ERROR: UPGRADE FAILED - IMPROVE ERROR +# +Run mysql_upgrade with unauthorized access +Version check failed. Got the following error when calling the 'mysql' command line client +ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) +FATAL ERROR: Upgrade failed +# # MDEV-4332 Increase username length from 16 characters # MDEV-6068, MDEV-6178 mysql_upgrade breaks databases with long user names # diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 3942f517e7c..a19d906b645 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -2100,3 +2100,16 @@ count(*) 40960 drop table t1; set names default; +create table t2 (a int, b int, c int, d int, key x(a, b)); +insert into t2 values (2, 2, 2, 2), (3, 3, 3, 3), (4, 4, 4, 4), (5, 5, 5, 5), +(6, 6, 6, 6), (7, 7, 7, 7), (8, 8, 8, 8), (9, 9, 9, 9); +insert into t2 select * from t2; +insert into t2 values (0, 0, 0, 0), (1, 1, 1, 1); +analyze table t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK +select a, b from t2 where (a, b) in ((0, 0), (1, 1)); +a b +0 0 +1 1 +drop table t2; diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result index 11a1687e5bf..9a089106c76 100644 --- a/mysql-test/r/range_mrr_icp.result +++ b/mysql-test/r/range_mrr_icp.result @@ -2102,4 +2102,17 @@ count(*) 40960 drop table t1; set names default; +create table t2 (a int, b int, c int, d int, key x(a, b)); +insert into t2 values (2, 2, 2, 2), (3, 3, 3, 3), (4, 4, 4, 4), (5, 5, 5, 5), +(6, 6, 6, 6), (7, 7, 7, 7), (8, 8, 8, 8), (9, 9, 9, 9); +insert into t2 select * from t2; +insert into t2 values (0, 0, 0, 0), (1, 1, 1, 1); +analyze table t2; +Table Op Msg_type Msg_text +test.t2 analyze status OK +select a, b from t2 where (a, b) in ((0, 0), (1, 1)); +a b +0 0 +1 1 +drop table t2; set optimizer_switch=@mrr_icp_extra_tmp; diff --git a/mysql-test/suite/innodb/r/dropdb.result b/mysql-test/suite/innodb/r/dropdb.result new file mode 100644 index 00000000000..6b11b5e5205 --- /dev/null +++ b/mysql-test/suite/innodb/r/dropdb.result @@ -0,0 +1,9 @@ +# +# Bug #19929435 DROP DATABASE HANGS WITH MALFORMED TABLE +# +set session default_storage_engine=innodb; +create database `b`; +use `b`; +create table `#mysql50#q.q` select 1; +ERROR 42000: Incorrect table name '#mysql50#q.q' +drop database `b`; diff --git a/mysql-test/suite/innodb/t/dropdb.test b/mysql-test/suite/innodb/t/dropdb.test new file mode 100644 index 00000000000..7f5ac809d7c --- /dev/null +++ b/mysql-test/suite/innodb/t/dropdb.test @@ -0,0 +1,12 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #19929435 DROP DATABASE HANGS WITH MALFORMED TABLE +--echo # + +set session default_storage_engine=innodb; +create database `b`; +use `b`; +--error ER_WRONG_TABLE_NAME +create table `#mysql50#q.q` select 1; +drop database `b`; diff --git a/mysql-test/t/events_1.test b/mysql-test/t/events_1.test index 7b0012c7079..032d5ecd380 100644 --- a/mysql-test/t/events_1.test +++ b/mysql-test/t/events_1.test @@ -125,8 +125,7 @@ drop event existant; create table t_event3 (a int, b float); drop event if exists event3; -create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) - comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); +create event event3 on schedule every 50 + 10 minute starts date_add(curdate(), interval 5 minute) ends date_add(curdate(), interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); let $wait_condition=SELECT count(*)=0 from t_event3; --source include/wait_condition.inc select count(*) from t_event3; diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test index 0b9e1433c39..86de04a9aef 100644 --- a/mysql-test/t/mysql_upgrade.test +++ b/mysql-test/t/mysql_upgrade.test @@ -129,6 +129,13 @@ let $MYSQLD_DATADIR= `select @@datadir`; # so the following command should never fail. --remove_file $MYSQLD_DATADIR/mysql_upgrade_info +--echo # +--echo # Bug #21489398: MYSQL_UPGRADE: FATAL ERROR: UPGRADE FAILED - IMPROVE ERROR +--echo # + +--echo Run mysql_upgrade with unauthorized access +--error 1 +--exec $MYSQL_UPGRADE --skip-verbose --user=root --password=wrong_password 2>&1 # 5.5-only test (involves manual modification of system tables) --echo # diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 0b8e1a9b3f3..b73b09dffd5 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1677,3 +1677,15 @@ select count(*) from t1 ignore index (ix_fd) where fd <'😁'; drop table t1; set names default; + +# +# Bug#17755540 VALGRIND ERROR WHEN SETTING UP ROW COMPARATORS +# +create table t2 (a int, b int, c int, d int, key x(a, b)); +insert into t2 values (2, 2, 2, 2), (3, 3, 3, 3), (4, 4, 4, 4), (5, 5, 5, 5), + (6, 6, 6, 6), (7, 7, 7, 7), (8, 8, 8, 8), (9, 9, 9, 9); +insert into t2 select * from t2; +insert into t2 values (0, 0, 0, 0), (1, 1, 1, 1); +analyze table t2; +select a, b from t2 where (a, b) in ((0, 0), (1, 1)); +drop table t2; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index dd16e535eda..425a2b13d66 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -1,6 +1,6 @@ /* Copyright (c) 2002, 2013, Oracle and/or its affiliates - Copyright (c) 2009, 2013, Monty Program Ab + Copyright (c) 2009, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/packaging/rpm-oel/mysql.spec.in b/packaging/rpm-oel/mysql.spec.in index bb232fb404d..a76eaa114f8 100644 --- a/packaging/rpm-oel/mysql.spec.in +++ b/packaging/rpm-oel/mysql.spec.in @@ -301,6 +301,7 @@ Obsoletes: mysql-devel < %{version}-%{release} Obsoletes: mariadb-devel Provides: mysql-devel = %{version}-%{release} Provides: mysql-devel%{?_isa} = %{version}-%{release} +Conflicts: mysql-connector-c-devel < 6.2 %description devel This package contains the development header files and libraries necessary @@ -323,6 +324,7 @@ Obsoletes: mysql-libs < %{version}-%{release} Obsoletes: mariadb-libs Provides: mysql-libs = %{version}-%{release} Provides: mysql-libs%{?_isa} = %{version}-%{release} +Conflicts: mysql-connector-c-shared < 6.2 %description libs This package contains the shared libraries for MySQL client @@ -620,7 +622,7 @@ rm -r $(readlink var) var %pre server /usr/sbin/groupadd -g 27 -o -r mysql >/dev/null 2>&1 || : -/usr/sbin/useradd -M -N -g mysql -o -r -d /var/lib/mysql -s /bin/bash \ +/usr/sbin/useradd -M %{!?el5:-N} -g mysql -o -r -d /var/lib/mysql -s /bin/bash \ -c "MySQL Server" -u 27 mysql >/dev/null 2>&1 || : %post server @@ -913,6 +915,9 @@ fi %endif %changelog +* Tue Sep 29 2015 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.47-1 +- Added conflicts to mysql-connector-c-shared dependencies + * Tue Jul 22 2014 Balasubramanian Kandasamy <balasubramanian.kandasamy@oracle.com> - 5.5.39-5 - Provide mysql-compat-server dependencies diff --git a/plugin/daemon_example/daemon_example.cc b/plugin/daemon_example/daemon_example.cc index 09b81caeaf4..35376a8ec32 100644 --- a/plugin/daemon_example/daemon_example.cc +++ b/plugin/daemon_example/daemon_example.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights + reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -46,7 +47,6 @@ pthread_handler_t mysql_heartbeat(void *p) DBUG_ENTER("mysql_heartbeat"); struct mysql_heartbeat_context *con= (struct mysql_heartbeat_context *)p; char buffer[HEART_STRING_BUFFER]; - unsigned int x= 0; time_t result; struct tm tm_tmp; @@ -65,7 +65,6 @@ pthread_handler_t mysql_heartbeat(void *p) tm_tmp.tm_min, tm_tmp.tm_sec); my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0)); - x++; } DBUG_RETURN(0); @@ -174,6 +173,13 @@ static int daemon_example_plugin_deinit(void *p __attribute__ ((unused))) tm_tmp.tm_min, tm_tmp.tm_sec); my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0)); + + /* + Need to wait for the hearbeat thread to terminate before closing + the file it writes to and freeing the memory it uses. + */ + pthread_join(con->heartbeat_thread, NULL); + my_close(con->heartbeat_file, MYF(0)); my_free(con); diff --git a/regex/main.c b/regex/main.c index f5b591907cf..d35d5a93734 100644 --- a/regex/main.c +++ b/regex/main.c @@ -425,7 +425,8 @@ char *should; (sub.rm_so != -1 && sub.rm_eo == -1) || (sub.rm_so != -1 && sub.rm_so < 0) || (sub.rm_eo != -1 && sub.rm_eo < 0) ) { - sprintf(grump, "start %ld end %ld", (long)sub.rm_so, + snprintf(grump, sizeof(grump), + "start %ld end %ld", (long)sub.rm_so, (long)sub.rm_eo); return(grump); } @@ -438,7 +439,8 @@ char *should; /* check for in range */ if ((int) sub.rm_eo > (int) strlen(str)) { - sprintf(grump, "start %ld end %ld, past end of string", + snprintf(grump, sizeof(grump), + "start %ld end %ld, past end of string", (long)sub.rm_so, (long)sub.rm_eo); return(grump); } @@ -449,13 +451,15 @@ char *should; /* check for not supposed to match */ if (should == NULL) { - sprintf(grump, "matched `%.*s'", len, p); + snprintf(grump, sizeof(grump), + "matched `%.*s'", len, p); return(grump); } /* check for wrong match */ if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) { - sprintf(grump, "matched `%.*s' instead", len, p); + snprintf(grump, sizeof(grump), + "matched `%.*s' instead", len, p); return(grump); } if (shlen > 0) @@ -468,7 +472,8 @@ char *should; if (shlen == 0) shlen = 1; /* force check for end-of-string */ if (strncmp(p, at, shlen) != 0) { - sprintf(grump, "matched null at `%.20s'", p); + snprintf(grump, sizeof(grump), + "matched null at `%.20s'", p); return(grump); } return(NULL); @@ -501,7 +506,7 @@ char *name; static char efbuf[100]; my_regex_t re; - sprintf(efbuf, "REG_%s", name); + snprintf(efbuf, sizeof(efbuf), "REG_%s", name); assert(strlen(efbuf) < sizeof(efbuf)); re.re_endp = efbuf; (void) my_regerror(REG_ATOI, &re, efbuf, sizeof(efbuf)); diff --git a/sql/field.h b/sql/field.h index b20bedbecc9..4c79847228e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -349,7 +349,7 @@ public: DBUG_ENTER("Field::pack_length_from_metadata"); DBUG_RETURN(field_metadata); } - virtual uint row_pack_length() { return 0; } + virtual uint row_pack_length() const { return 0; } virtual int save_field_metadata(uchar *first_byte) { return do_save_field_metadata(first_byte); } @@ -757,7 +757,7 @@ public: int store_decimal(const my_decimal *); my_decimal *val_decimal(my_decimal *); uint is_equal(Create_field *new_field); - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } uint32 pack_length_from_metadata(uint field_metadata) { uint32 length= pack_length(); DBUG_PRINT("result", ("pack_length_from_metadata(%d): %u", @@ -940,7 +940,7 @@ public: uint size_of() const { return sizeof(*this); } uint32 pack_length() const { return (uint32) bin_size; } uint pack_length_from_metadata(uint field_metadata); - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } bool compatible_field_size(uint field_metadata, Relay_log_info *rli, uint16 mflags, int *order_var); uint is_equal(Create_field *new_field); @@ -1189,7 +1189,7 @@ public: int cmp(const uchar *,const uchar *); void sort_string(uchar *buff,uint length); uint32 pack_length() const { return sizeof(float); } - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } void sql_type(String &str) const; private: int do_save_field_metadata(uchar *first_byte); @@ -1229,7 +1229,7 @@ public: int cmp(const uchar *,const uchar *); void sort_string(uchar *buff,uint length); uint32 pack_length() const { return sizeof(double); } - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } void sql_type(String &str) const; private: int do_save_field_metadata(uchar *first_byte); @@ -1718,7 +1718,7 @@ public: } bool compatible_field_size(uint field_metadata, Relay_log_info *rli, uint16 mflags, int *order_var); - uint row_pack_length() { return field_length; } + uint row_pack_length() const { return field_length; } int pack_cmp(const uchar *a,const uchar *b,uint key_length, bool insert_or_update); int pack_cmp(const uchar *b,uint key_length,bool insert_or_update); @@ -1768,7 +1768,7 @@ public: enum_field_types type() const { return MYSQL_TYPE_VARCHAR; } bool match_collation_to_optimize_range() const { return TRUE; } enum ha_base_keytype key_type() const; - uint row_pack_length() { return field_length; } + uint row_pack_length() const { return field_length; } bool zero_pack() const { return 0; } int reset(void) { bzero(ptr,field_length+length_bytes); return 0; } uint32 pack_length() const { return (uint32) field_length+length_bytes; } @@ -1893,7 +1893,7 @@ public: */ uint32 pack_length_no_ptr() const { return (uint32) (packlength); } - uint row_pack_length() { return pack_length_no_ptr(); } + uint row_pack_length() const { return pack_length_no_ptr(); } uint32 sort_length() const; virtual uint32 max_data_length() const { @@ -2055,7 +2055,7 @@ public: enum_field_types real_type() const { return MYSQL_TYPE_ENUM; } uint pack_length_from_metadata(uint field_metadata) { return (field_metadata & 0x00ff); } - uint row_pack_length() { return pack_length(); } + uint row_pack_length() const { return pack_length(); } virtual bool zero_pack() const { return 0; } bool optimize_range(uint idx, uint part) { return 0; } bool eq_def(Field *field); @@ -2176,7 +2176,7 @@ public: uint32 pack_length() const { return (uint32) (field_length + 7) / 8; } uint32 pack_length_in_rec() const { return bytes_in_rec; } uint pack_length_from_metadata(uint field_metadata); - uint row_pack_length() + uint row_pack_length() const { return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); } bool compatible_field_size(uint metadata, Relay_log_info *rli, uint16 mflags, int *order_var); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0c48592eb9f..d5f50871ddf 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2013, Monty Program Ab. + Copyright (c) 2009, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 9504be57a90..babe1d76ea4 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1,7 +1,7 @@ #ifndef ITEM_CMPFUNC_INCLUDED #define ITEM_CMPFUNC_INCLUDED -/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. - Copyright (c) 2009, 2011, Monty Program Ab. +/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. + Copyright (c) 2009, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/item_func.cc b/sql/item_func.cc index 9a38fc60b0d..252ca9e504b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. Copyright (c) 2009, 2015, MariaDB This program is free software; you can redistribute it and/or modify @@ -6280,9 +6280,7 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) table= 0; for (uint i=1 ; i < arg_count ; i++) { - item=args[i]; - if (item->type() == Item::REF_ITEM) - args[i]= item= *((Item_ref *)item)->ref; + item= args[i]= args[i]->real_item(); /* When running in PS mode, some Item_field's can already be replaced to Item_func_conv_charset during PREPARE time. This is possible @@ -6295,7 +6293,7 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) if (!thd->stmt_arena->is_stmt_execute() && item->type() != Item::FIELD_ITEM) { - my_error(ER_WRONG_ARGUMENTS, MYF(0), "AGAINST"); + my_error(ER_WRONG_ARGUMENTS, MYF(0), "MATCH"); return TRUE; } /* diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 1107945ae99..3020faf29d3 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2002, 2012, Oracle and/or its affiliates. - Copyright (c) 2010, 2012, Monty Program Ab +/* Copyright (c) 2002, 2015, Oracle and/or its affiliates. + Copyright (c) 2010, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1748,6 +1748,27 @@ Item_in_subselect::single_value_transformer(JOIN *join) runtime created Ref item which is deleted at the end of the statement. Thus one of 'substitution' arguments can be broken in case of PS. + + @todo + Why do we use real_item()/substitutional_item() instead of the plain + left_expr? + Because left_expr might be a rollbackable item, and we fail to properly + rollback all copies of left_expr at end of execution, so we want to + avoid creating copies of left_expr as much as possible, so we use + real_item() instead. + Doing a proper rollback is difficult: the change was registered for the + original item which was the left argument of IN. Then this item was + copied to left_expr, which is copied below to substitution->args[0]. To + do a proper rollback, we would have to restore the content + of both copies as well as the original item. There might be more copies, + if AND items have been constructed. + The same applies to the right expression. + However, using real_item()/substitutional_item() brings its own + problems: for example, we lose information that the item is an outer + reference; the item can thus wrongly be considered for a Keyuse (causing + bug#17766653). + When WL#6570 removes the "rolling back" system, all + real_item()/substitutional_item() in this file should be removed. */ substitution= func->create(left_expr, where_item); have_to_be_excluded= 1; @@ -2034,6 +2055,9 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, } else { + /* + Grep for "WL#6570" to see the relevant comment about real_item. + */ Item *item= (Item*) select_lex->item_list.head()->real_item(); if (select_lex->table_list.elements) diff --git a/sql/mysqld.h b/sql/mysqld.h index 3480d02365b..24ae9ec7a61 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. + Copyright (c) 2010, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -336,6 +337,7 @@ extern mysql_mutex_t LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count; extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count; #ifdef HAVE_OPENSSL +extern char* des_key_file; extern mysql_mutex_t LOCK_des_key_file; #endif extern mysql_mutex_t LOCK_server_started; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 4588c741cb4..da7c3f17c63 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7326,6 +7326,8 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user, DBUG_RETURN(FALSE); } + mysql_mutex_lock(&acl_cache->lock); + /* check for matching WITH PROXY rights */ for (uint i=0; i < acl_proxy_users.elements; i++) { @@ -7338,10 +7340,12 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user, proxy->get_with_grant()) { DBUG_PRINT("info", ("found")); + mysql_mutex_unlock(&acl_cache->lock); DBUG_RETURN(FALSE); } } + mysql_mutex_unlock(&acl_cache->lock); my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0), thd->security_ctx->user, thd->security_ctx->host_or_ip); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 640ee5d1ec9..52e059b5ef8 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1999,7 +1999,7 @@ public: */ MDL_request grl_protection; - Delayed_insert() + Delayed_insert(SELECT_LEX *current_select) :locks_in_memory(0), table(0),tables_in_use(0),stacked_inserts(0), status(0), handler_thread_initialized(FALSE), group_count(0) { @@ -2009,7 +2009,7 @@ public: strmake_buf(thd.security_ctx->priv_user, thd.security_ctx->user); thd.current_tablenr=0; thd.command=COM_DELAYED_INSERT; - thd.lex->current_select= 0; // for my_message_sql + thd.lex->current_select= current_select; thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock() /* Prevent changes to global.lock_wait_timeout from affecting @@ -2186,7 +2186,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request, */ if (! (di= find_handler(thd, table_list))) { - if (!(di= new Delayed_insert())) + if (!(di= new Delayed_insert(thd->lex->current_select))) goto end_create; mysql_mutex_lock(&LOCK_thread_count); thread_count++; @@ -2817,6 +2817,16 @@ pthread_handler_t handle_delayed_insert(void *arg) if (di->open_and_lock_table()) goto err; + /* + INSERT DELAYED generally expects thd->lex->current_select to be NULL, + since this is not an attribute of the current thread. This can lead to + problems if the thread that spawned the current one disconnects. + current_select will then point to freed memory. But current_select is + required to resolve the partition function. So, after fulfilling that + requirement, we set the current_select to 0. + */ + thd->lex->current_select= NULL; + /* Tell client that the thread is initialized */ mysql_cond_signal(&di->cond_client); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index c61c9101a36..6727b2a0182 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2002, 2013, Oracle and/or its affiliates. - Copyright (c) 2008, 2013, Monty Program Ab +/* Copyright (c) 2002, 2015, Oracle and/or its affiliates. + Copyright (c) 2008, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -3781,8 +3781,8 @@ Prepared_statement::swap_prepared_statement(Prepared_statement *copy) swap_variables(LEX_STRING, name, copy->name); /* Ditto */ swap_variables(char *, db, copy->db); + swap_variables(size_t, db_length, copy->db_length); - DBUG_ASSERT(db_length == copy->db_length); DBUG_ASSERT(param_count == copy->param_count); DBUG_ASSERT(thd == copy->thd); last_error[0]= '\0'; diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 914b9026014..b9328addc6a 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ #include "sql_repl.h" // reset_master, reset_slave #include "rpl_mi.h" // Master_info::data_lock #include "debug_sync.h" +#include "des_key_file.h" static void disable_checkpoints(THD *thd); @@ -301,7 +302,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, } } #endif -#ifdef OPENSSL +#ifdef HAVE_OPENSSL if (options & REFRESH_DES_KEY_FILE) { if (des_key_file && load_des_key_file(des_key_file)) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ef1b5b0014e..1b1464049df 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4114,6 +4114,17 @@ add_key_field(JOIN *join, Field *field, bool eq_func, Item **value, uint num_values, table_map usable_tables, SARGABLE_PARAM **sargables) { + if (field->table->reginfo.join_tab == NULL) + { + /* + Due to a bug in IN-to-EXISTS (grep for real_item() in item_subselect.cc + for more info), an index over a field from an outer query might be + considered here, which is incorrect. Their query has been fully + optimized already so their reginfo.join_tab is NULL and we reject them. + */ + return; + } + uint optimize= 0; if (eq_func && ((join->is_allowed_hash_join_access() && @@ -14904,8 +14915,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, uint temp_pool_slot=MY_BIT_NONE; uint fieldnr= 0; ulong reclength, string_total_length; - bool using_unique_constraint= 0; - bool use_packed_rows= 0; + bool using_unique_constraint= false; + bool use_packed_rows= false; bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS); char *tmpname,path[FN_REFLEN]; uchar *pos, *group_buff, *bitmaps; @@ -14979,10 +14990,10 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, */ (*tmp->item)->marker=4; // Store null in key if ((*tmp->item)->too_big_for_varchar()) - using_unique_constraint=1; + using_unique_constraint= true; } if (param->group_length >= MAX_BLOB_WIDTH) - using_unique_constraint=1; + using_unique_constraint= true; if (group) distinct=0; // Can't use distinct } @@ -15236,12 +15247,14 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, *blob_field++= fieldnr; blob_count++; } + if (new_field->real_type() == MYSQL_TYPE_STRING || new_field->real_type() == MYSQL_TYPE_VARCHAR) { string_count++; string_total_length+= new_field->pack_length(); } + if (item->marker == 4 && item->maybe_null) { group_null_items++; @@ -15294,7 +15307,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, if (group && (param->group_parts > table->file->max_key_parts() || param->group_length > table->file->max_key_length())) - using_unique_constraint=1; + using_unique_constraint= true; } else { @@ -15431,7 +15444,9 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields, field->real_type() == MYSQL_TYPE_STRING && length >= MIN_STRING_LENGTH_TO_PACK_ROWS) recinfo->type= FIELD_SKIP_ENDSPACE; - else if (field->real_type() == MYSQL_TYPE_VARCHAR) + else if (use_packed_rows && + field->real_type() == MYSQL_TYPE_VARCHAR && + length >= MIN_STRING_LENGTH_TO_PACK_ROWS) recinfo->type= FIELD_VARCHAR; else recinfo->type= FIELD_NORMAL; @@ -16202,7 +16217,10 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo, start_recinfo, share->uniques, &uniquedef, &create_info, - HA_CREATE_TMP_TABLE))) + HA_CREATE_TMP_TABLE | + ((share->db_create_options & HA_OPTION_PACK_RECORD) ? + HA_PACK_RECORD : 0) + ))) { table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->db_stat=0; diff --git a/sql/table.cc b/sql/table.cc index f521056aaee..db18214165e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. +/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. Copyright (c) 2008, 2015, MariaDB This program is free software; you can redistribute it and/or modify @@ -2445,21 +2445,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, outparam->record[1]= outparam->record[0]; // Safety } -#ifdef HAVE_valgrind - /* - We need this because when we read var-length rows, we are not updating - bytes after end of varchar - */ - if (records > 1) - { - memcpy(outparam->record[0], share->default_values, share->rec_buff_length); - memcpy(outparam->record[1], share->default_values, share->null_bytes); - if (records > 2) - memcpy(outparam->record[1], share->default_values, - share->rec_buff_length); - } -#endif - if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root, (uint) ((share->fields+1)* sizeof(Field*))))) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 95216d30aae..f2a2eeca467 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6649,7 +6649,8 @@ create_table_def( /* MySQL does the name length check. But we do additional check on the name length here */ - if (strlen(table_name) > MAX_FULL_NAME_LEN) { + const size_t table_name_len = strlen(table_name); + if (table_name_len > MAX_FULL_NAME_LEN) { push_warning_printf( (THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TABLE_NAME, @@ -6658,6 +6659,15 @@ create_table_def( DBUG_RETURN(ER_TABLE_NAME); } + if (table_name[table_name_len - 1] == '/') { + push_warning_printf( + (THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_TABLE_NAME, + "InnoDB: Table name is empty"); + + DBUG_RETURN(ER_WRONG_TABLE_NAME); + } + n_cols = form->s->fields; /* We pass 0 as the space id, and determine at a lower level the space diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index c4f23da85aa..da3ea786af4 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -736,6 +736,10 @@ not_consistent: fprintf(stderr, "InnoDB: No valid checkpoint found.\n" + "InnoDB: If you are attempting downgrade" + " from MySQL 5.7.9 or later,\n" + "InnoDB: please refer to " REFMAN + "upgrading-downgrading.html\n" "InnoDB: If this error appears when you are" " creating an InnoDB database,\n" "InnoDB: the problem may be that during" diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index d4cc31368dd..bdd932b86fe 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -1,5 +1,6 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates + Copyright (c) 2000, 2015, Oracle and/or its affiliates + Copyright (c) 2010, 2015, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -473,7 +474,6 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_del[i]=HA_OFFSET_ERROR; unique_key_parts=0; - offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; for (i=0, uniquedef=uniquedefs ; i < uniques ; i++ , uniquedef++) { uniquedef->key=keys+i; @@ -739,7 +739,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, #endif } /* Create extra keys for unique definitions */ - offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; + offset=real_reclength - uniques * MI_UNIQUE_HASH_LENGTH; bzero((char*) &tmp_keydef,sizeof(tmp_keydef)); bzero((char*) &tmp_keyseg,sizeof(tmp_keyseg)); for (i=0; i < uniques ; i++) |