summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <jani@a193-229-222-105.elisa-laajakaista.fi>2006-02-05 11:06:29 +0200
committerunknown <jani@a193-229-222-105.elisa-laajakaista.fi>2006-02-05 11:06:29 +0200
commitfd03e915ea8278a3f4f604e815302f05dbf042e7 (patch)
tree388a5c39bbaaa03a0899af811382b027e9edda81
parent4f40b7be9abe32bf7216541bcab68261fb4ea7ac (diff)
parentfb84189349c1e3af2df8ae03e3030611b715652a (diff)
downloadmariadb-git-fd03e915ea8278a3f4f604e815302f05dbf042e7.tar.gz
Merge jamppa@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.1-new configure.in: Auto merged sql/mysqld.cc: Auto merged sql/set_var.cc: Auto merged
-rw-r--r--.bzrignore3
-rw-r--r--Docs/Makefile.am10
-rw-r--r--client/mysqladmin.cc1
-rw-r--r--client/mysqlbinlog.cc9
-rw-r--r--client/mysqldump.c27
-rw-r--r--cmd-line-utils/libedit/history.c4
-rw-r--r--configure.in11
-rw-r--r--include/my_base.h3
-rw-r--r--libmysql/Makefile.shared2
-rw-r--r--libmysql/libmysql.c4
-rw-r--r--libmysql/libmysql.ver.in1
-rw-r--r--mysql-test/r/fulltext2.result5
-rw-r--r--mysql-test/r/information_schema.result13
-rw-r--r--mysql-test/r/rpl_multi_update4.result25
-rw-r--r--mysql-test/r/rpl_sp.result13
-rw-r--r--mysql-test/r/sp-error.result19
-rw-r--r--mysql-test/r/sp-security.result21
-rw-r--r--mysql-test/r/sp.result58
-rw-r--r--mysql-test/r/sp_trans.result2
-rw-r--r--mysql-test/r/subselect.result6
-rw-r--r--mysql-test/r/system_mysql_db.result5
-rw-r--r--mysql-test/r/type_float.result22
-rw-r--r--mysql-test/r/type_varchar.result7
-rw-r--r--mysql-test/t/disabled.def2
-rw-r--r--mysql-test/t/fulltext2.test8
-rw-r--r--mysql-test/t/func_math.test2
-rw-r--r--mysql-test/t/information_schema.test23
-rw-r--r--mysql-test/t/rpl_multi_update4-slave.opt1
-rw-r--r--mysql-test/t/rpl_multi_update4.test44
-rw-r--r--mysql-test/t/rpl_sp.test36
-rw-r--r--mysql-test/t/sp-error.test27
-rw-r--r--mysql-test/t/sp-security.test44
-rw-r--r--mysql-test/t/sp.test49
-rw-r--r--mysql-test/t/sp_trans.test2
-rw-r--r--mysql-test/t/type_float.test17
-rw-r--r--mysql-test/t/type_varchar.test16
-rw-r--r--mysys/default_modify.c2
-rw-r--r--mysys/mf_iocache2.c10
-rw-r--r--mysys/my_bitmap.c2
-rw-r--r--mysys/my_error.c3
-rw-r--r--mysys/my_lib.c2
-rw-r--r--scripts/mysql_fix_privilege_tables.sql6
-rw-r--r--server-tools/instance-manager/parse.cc2
-rw-r--r--sql-common/client.c2
-rw-r--r--sql/field.cc30
-rw-r--r--sql/field.h4
-rw-r--r--sql/ha_archive.cc7
-rw-r--r--sql/ha_myisam.cc17
-rw-r--r--sql/item.cc4
-rw-r--r--sql/item_func.cc13
-rw-r--r--sql/log_event.cc4
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/opt_range.cc7
-rw-r--r--sql/opt_range.h2
-rw-r--r--sql/protocol.cc18
-rw-r--r--sql/repl_failsafe.cc3
-rw-r--r--sql/set_var.cc1
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/slave.cc38
-rw-r--r--sql/slave.h2
-rw-r--r--sql/sp_head.cc54
-rw-r--r--sql/sp_head.h2
-rw-r--r--sql/spatial.h2
-rw-r--r--sql/sql_acl.cc8
-rw-r--r--sql/sql_db.cc112
-rw-r--r--sql/sql_help.cc2
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_parse.cc77
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_repl.cc12
-rw-r--r--sql/sql_select.cc8
-rw-r--r--sql/sql_show.cc35
-rw-r--r--sql/sql_test.cc2
-rw-r--r--sql/sql_yacc.yy15
-rw-r--r--sql/table.cc5
-rw-r--r--sql/table.h1
-rw-r--r--sql/uniques.cc122
-rw-r--r--storage/myisam/ft_update.c4
-rw-r--r--storage/myisam/mi_delete.c3
-rw-r--r--storage/myisam/myisampack.c2
-rw-r--r--storage/myisam/sort.c3
-rw-r--r--storage/ndb/include/logger/LogHandler.hpp13
-rw-r--r--storage/ndb/include/logger/Logger.hpp5
-rw-r--r--storage/ndb/include/mgmapi/mgmapi.h16
-rw-r--r--storage/ndb/include/mgmcommon/ConfigRetriever.hpp3
-rw-r--r--storage/ndb/src/common/logger/FileLogHandler.cpp17
-rw-r--r--storage/ndb/src/common/logger/LogHandler.cpp29
-rw-r--r--storage/ndb/src/common/logger/Logger.cpp11
-rw-r--r--storage/ndb/src/common/logger/SysLogHandler.cpp1
-rw-r--r--storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp3
-rw-r--r--storage/ndb/src/common/util/SocketServer.cpp2
-rw-r--r--storage/ndb/src/kernel/main.cpp5
-rw-r--r--storage/ndb/src/kernel/vm/Configuration.cpp3
-rw-r--r--storage/ndb/src/kernel/vm/Configuration.hpp2
-rw-r--r--storage/ndb/src/mgmapi/mgmapi.cpp19
-rw-r--r--storage/ndb/src/mgmclient/CommandInterpreter.cpp23
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.cpp153
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.hpp11
-rw-r--r--storage/ndb/src/mgmsrv/Services.cpp15
-rw-r--r--storage/ndb/src/mgmsrv/Services.hpp1
-rw-r--r--storage/ndb/src/mgmsrv/main.cpp61
-rw-r--r--storage/ndb/tools/ndb_size.pl2
-rw-r--r--support-files/MySQL-shared-compat.spec.sh11
-rw-r--r--tests/mysql_client_test.c84
-rw-r--r--zlib/Makefile.am2
-rw-r--r--zlib/README.MySQL9
-rw-r--r--zlib/gzio.c4
-rw-r--r--zlib/zconf.h6
108 files changed, 1279 insertions, 430 deletions
diff --git a/.bzrignore b/.bzrignore
index 16211ff2ecf..50218bc2dc3 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -48,6 +48,7 @@
50
=6
BUILD/compile-pentium-maintainer
+BitKeeper/etc/RESYNC_TREE
BitKeeper/etc/config
BitKeeper/etc/csets
BitKeeper/etc/csets-in
@@ -295,6 +296,7 @@ libmysql/*.ds?
libmysql/*.vcproj
libmysql/conf_to_src
libmysql/debug/libmysql.exp
+libmysql/libmysql.ver
libmysql/my_static.h
libmysql/my_time.c
libmysql/mysys_priv.h
@@ -1611,4 +1613,3 @@ vio/viotest-sslconnect.cpp
vio/viotest.cpp
zlib/*.ds?
zlib/*.vcproj
-BitKeeper/etc/RESYNC_TREE
diff --git a/Docs/Makefile.am b/Docs/Makefile.am
index 542c82d8f58..f512aa9e29e 100644
--- a/Docs/Makefile.am
+++ b/Docs/Makefile.am
@@ -45,22 +45,22 @@ CLEAN_FILES: $(TXT_FILES)
GT = $(srcdir)/Support/generate-text-files.pl
../INSTALL-SOURCE: mysql.info $(GT)
- perl -w $(GT) $< "installing-source" "windows-source-build" > $@
+ perl -w $(GT) mysql.info "installing-source" "windows-source-build" > $@
../INSTALL-WIN-SOURCE: mysql.info $(GT)
- perl -w $(GT) $< "windows-source-build" "post-installation" > $@
+ perl -w $(GT) mysql.info "windows-source-build" "post-installation" > $@
# We put the description for the binary installation here so that
# people who download source wont have to see it. It is moved up to
# the toplevel by the script that makes the binary tar files.
INSTALL-BINARY: mysql.info $(GT)
- perl -w $(GT) $< "installing-binary" "installing-source" > $@
+ perl -w $(GT) mysql.info "installing-binary" "installing-source" > $@
../EXCEPTIONS-CLIENT: mysql.info $(GT)
- perl -w $(GT) $< "mysql-floss-license-exception" "function-index" > $@
+ perl -w $(GT) mysql.info "mysql-floss-license-exception" "function-index" > $@
../support-files/MacOSX/ReadMe.txt: mysql.info $(GT)
- perl -w $(GT) $< "mac-os-x-installation" "netware-installation" > $@
+ perl -w $(GT) mysql.info "mac-os-x-installation" "netware-installation" > $@
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 8d2e040b21f..5b52d524f8e 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -569,6 +569,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
return -1;
}
mysql_close(mysql); /* Close connection to avoid error messages */
+ argc=1; /* force SHUTDOWN to be the last command */
if (got_pidfile)
{
if (opt_verbose)
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index d86e3a44746..96792d0ffcb 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1293,12 +1293,13 @@ at offset %lu ; this could be a log format error or read error",
}
else if (buf[4] == ROTATE_EVENT)
{
+ Log_event *ev;
my_b_seek(file, tmp_pos); /* seek back to event's start */
- if (!Log_event::read_log_event(file, *description_event))
+ if (!(ev= Log_event::read_log_event(file, *description_event)))
/* EOF can't be hit here normally, so it's a real error */
- die("Could not read a Rotate_log_event event \
-at offset %lu ; this could be a log format error or read error",
- tmp_pos);
+ die("Could not read a Rotate_log_event event at offset %lu ;"
+ " this could be a log format error or read error", tmp_pos);
+ delete ev;
}
else
break;
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 9c495a70ea9..6521e9183f3 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -1316,7 +1316,7 @@ static uint dump_routines_for_db(char *db)
fprintf(sql_file, "DELIMITER ;\n");
if (lock_tables)
- mysql_query_with_error_report(sock, 0, "UNLOCK TABLES");
+ VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
DBUG_RETURN(0);
}
@@ -2139,7 +2139,10 @@ static void dump_table(char *table, char *db)
else
res=mysql_store_result(sock);
if (!res)
+ {
DB_error(sock, "when retrieving data from server");
+ goto err;
+ }
if (verbose)
fprintf(stderr, "-- Retrieving rows...\n");
if (mysql_num_fields(res) != num_fields)
@@ -2794,7 +2797,7 @@ static int dump_all_tables_in_db(char *database)
check_io(md_result_file);
}
if (lock_tables)
- mysql_query_with_error_report(sock, 0, "UNLOCK TABLES");
+ VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
return 0;
} /* dump_all_tables_in_db */
@@ -2849,23 +2852,23 @@ static my_bool dump_all_views_in_db(char *database)
check_io(md_result_file);
}
if (lock_tables)
- mysql_query(sock,"UNLOCK TABLES");
+ VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
return 0;
} /* dump_all_tables_in_db */
/*
- get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
- table name from the server for the table name given on the command line.
- we do this because the table name given on the command line may be a
+ get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
+ table name from the server for the table name given on the command line.
+ we do this because the table name given on the command line may be a
different case (e.g. T1 vs t1)
-
+
RETURN
int - 0 if a tablename was retrieved. 1 if not
*/
-static int get_actual_table_name(const char *old_table_name,
- char *new_table_name,
+static int get_actual_table_name(const char *old_table_name,
+ char *new_table_name,
int buf_size)
{
int retval;
@@ -2877,7 +2880,7 @@ static int get_actual_table_name(const char *old_table_name,
/* Check memory for quote_for_like() */
DBUG_ASSERT(2*sizeof(old_table_name) < sizeof(show_name_buff));
- my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
+ my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
quote_for_like(old_table_name, show_name_buff));
if (mysql_query_with_error_report(sock, 0, query))
@@ -2886,7 +2889,7 @@ static int get_actual_table_name(const char *old_table_name,
}
retval = 1;
-
+
if ((table_res= mysql_store_result(sock)))
{
my_ulonglong num_rows= mysql_num_rows(table_res);
@@ -3008,7 +3011,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
check_io(md_result_file);
}
if (lock_tables)
- mysql_query_with_error_report(sock, 0, "UNLOCK TABLES");
+ VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
DBUG_RETURN(0);
} /* dump_selected_tables */
diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c
index 1da6a864181..c0fa7cc717d 100644
--- a/cmd-line-utils/libedit/history.c
+++ b/cmd-line-utils/libedit/history.c
@@ -676,8 +676,8 @@ history_load(History *h, const char *fname)
(void) strunvis(ptr, line);
line[sz] = c;
if (HENTER(h, &ev, ptr) == -1) {
- h_free((ptr_t)ptr);
- return -1;
+ i = -1;
+ goto oomem;
}
}
oomem:
diff --git a/configure.in b/configure.in
index 372417973dc..bdaa1f5166e 100644
--- a/configure.in
+++ b/configure.in
@@ -13,7 +13,8 @@ AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
DOT_FRM_VERSION=6
# See the libtool docs for information on how to do shared lib versions.
-SHARED_LIB_VERSION=15:0:0
+SHARED_LIB_MAJOR_VERSION=15
+SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
# Set all version vars based on $VERSION. How do we do this more elegant ?
# Remember that regexps needs to quote [ and ] since this is run through m4
@@ -60,6 +61,7 @@ AC_DEFINE_UNQUOTED([PROTOCOL_VERSION], [$PROTOCOL_VERSION],
AC_SUBST(DOT_FRM_VERSION)
AC_DEFINE_UNQUOTED([DOT_FRM_VERSION], [$DOT_FRM_VERSION],
[Version of .frm files])
+AC_SUBST(SHARED_LIB_MAJOR_VERSION)
AC_SUBST(SHARED_LIB_VERSION)
AC_SUBST(AVAILABLE_LANGUAGES)
@@ -339,6 +341,13 @@ fi
MYSQL_PROG_AR
+# libmysqlclient versioning when linked with GNU ld.
+if $LD --version 2>/dev/null|grep -q GNU; then
+ LD_VERSION_SCRIPT="-Wl,--version-script=\$(top_srcdir)/libmysql/libmysql.ver"
+ AC_CONFIG_FILES(libmysql/libmysql.ver)
+fi
+AC_SUBST(LD_VERSION_SCRIPT)
+
# Avoid bug in fcntl on some versions of linux
AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os")
# Any variation of Linux
diff --git a/include/my_base.h b/include/my_base.h
index 5962775fb57..168625f4a87 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -426,7 +426,8 @@ enum ha_base_keytype {
enum en_fieldtype {
FIELD_LAST=-1,FIELD_NORMAL,FIELD_SKIP_ENDSPACE,FIELD_SKIP_PRESPACE,
FIELD_SKIP_ZERO,FIELD_BLOB,FIELD_CONSTANT,FIELD_INTERVALL,FIELD_ZERO,
- FIELD_VARCHAR,FIELD_CHECK
+ FIELD_VARCHAR,FIELD_CHECK,
+ FIELD_enum_val_count
};
enum data_file_type {
diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared
index a4d616f936a..c4c9c0036e2 100644
--- a/libmysql/Makefile.shared
+++ b/libmysql/Makefile.shared
@@ -77,7 +77,7 @@ mysysobjects2 = my_lib.lo
mysysobjects = $(mysysobjects1) $(mysysobjects2)
target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
$(sql_cmn_objects) $(vio_objects) $(sqlobjects)
-target_ldflags = -version-info @SHARED_LIB_VERSION@
+target_ldflags = -version-info @SHARED_LIB_VERSION@ @LD_VERSION_SCRIPT@
vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
$(target)
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index e2ee44efffb..a77d1408383 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -818,7 +818,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
if ((*options->local_infile_init)(&li_ptr, net_filename,
options->local_infile_userdata))
{
- my_net_write(net,"",0); /* Server needs one packet */
+ VOID(my_net_write(net,"",0)); /* Server needs one packet */
net_flush(net);
strmov(net->sqlstate, unknown_sqlstate);
net->last_errno= (*options->local_infile_error)(li_ptr,
@@ -2817,7 +2817,7 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
{
switch (attr_type) {
case STMT_ATTR_UPDATE_MAX_LENGTH:
- *(ulong*) value= stmt->update_max_length;
+ *(my_bool*) value= stmt->update_max_length;
break;
case STMT_ATTR_CURSOR_TYPE:
*(ulong*) value= stmt->flags;
diff --git a/libmysql/libmysql.ver.in b/libmysql/libmysql.ver.in
new file mode 100644
index 00000000000..20eb0fd41bb
--- /dev/null
+++ b/libmysql/libmysql.ver.in
@@ -0,0 +1 @@
+libmysqlclient_@SHARED_LIB_MAJOR_VERSION@ { global: *; };
diff --git a/mysql-test/r/fulltext2.result b/mysql-test/r/fulltext2.result
index 72c6b2d22ed..f6a4b20bc22 100644
--- a/mysql-test/r/fulltext2.result
+++ b/mysql-test/r/fulltext2.result
@@ -234,5 +234,10 @@ insert into t1 values('test test '),('test'),('test'),('test'),
('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test');
delete from t1 limit 1;
+truncate table t1;
+insert into t1 values('ab c d');
+update t1 set a='ab c d';
+select * from t1 where match a against('ab c' in boolean mode);
+a
drop table t1;
set names latin1;
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index e367e063201..fe3c409744d 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1126,6 +1126,19 @@ DROP TABLE t1;
DROP VIEW v1;
DROP FUNCTION func1;
DROP FUNCTION func2;
+create database mysqltest;
+create table mysqltest.t1(a int);
+select table_schema from information_schema.tables where table_schema='mysqltest';
+table_schema
+drop database mysqltest;
+select column_type, group_concat(table_schema, '.', table_name), count(*) as num
+from information_schema.columns where
+table_schema='information_schema' and
+(column_type = 'varchar(7)' or column_type = 'varchar(20)')
+group by column_type order by num;
+column_type group_concat(table_schema, '.', table_name) num
+varchar(7) information_schema.ROUTINES,information_schema.VIEWS 2
+varchar(20) information_schema.COLUMNS,information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS 6
select * from information_schema.engines WHERE ENGINE="MyISAM";
ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS
MyISAM ENABLED Default engine as of MySQL 3.23 with great performance NO NO NO
diff --git a/mysql-test/r/rpl_multi_update4.result b/mysql-test/r/rpl_multi_update4.result
new file mode 100644
index 00000000000..f6dde65a35d
--- /dev/null
+++ b/mysql-test/r/rpl_multi_update4.result
@@ -0,0 +1,25 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists d1;
+drop database if exists d2;
+drop database if exists d2;
+create database d1;
+create table d1.t0 (id int);
+create database d2;
+use d2;
+create table t1 (id int);
+create table t2 (id int);
+insert into t1 values (1), (2), (3), (4), (5);
+insert into t2 select id + 3 from t1;
+update t1 join t2 using (id) set t1.id = 0;
+insert into d1.t0 values (0);
+use d1;
+select * from t0 where id=0;
+id
+0
+drop database d1;
+drop database d2;
diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result
index 1acb57f67d5..8aa0f445438 100644
--- a/mysql-test/r/rpl_sp.result
+++ b/mysql-test/r/rpl_sp.result
@@ -401,5 +401,18 @@ drop function f1;
select * from t1;
a
1
+DROP PROCEDURE IF EXISTS p1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(col VARCHAR(10));
+CREATE PROCEDURE p1(arg VARCHAR(10))
+INSERT INTO t1 VALUES(arg);
+CALL p1('test');
+SELECT * FROM t1;
+col
+test
+SELECT * FROM t1;
+col
+test
+DROP PROCEDURE p1;
drop table t1;
reset master;
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index a74a18375d5..d26f0029001 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -1115,3 +1115,22 @@ ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function
drop function bug11555_1;
drop table t1;
drop view v1;
+drop procedure if exists ` bug15658`;
+create procedure ``() select 1;
+ERROR 42000: Incorrect routine name ''
+create procedure ` `() select 1;
+ERROR 42000: Incorrect routine name ' '
+create procedure `bug15658 `() select 1;
+ERROR 42000: Incorrect routine name 'bug15658 '
+create procedure ``.bug15658() select 1;
+ERROR 42000: Incorrect database name ''
+create procedure `x `.bug15658() select 1;
+ERROR 42000: Incorrect database name 'x '
+create procedure ` bug15658`() select 1;
+call ` bug15658`();
+1
+1
+show procedure status;
+Db Name Type Definer Modified Created Security_type Comment
+test bug15658 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
+drop procedure ` bug15658`;
diff --git a/mysql-test/r/sp-security.result b/mysql-test/r/sp-security.result
index 614e670f25d..fbc6d64f9c9 100644
--- a/mysql-test/r/sp-security.result
+++ b/mysql-test/r/sp-security.result
@@ -263,3 +263,24 @@ CREATE VIEW v1 AS SELECT test.bug12812()|
ERROR 42000: execute command denied to user 'user_bug12812'@'localhost' for routine 'test.bug12812'
DROP USER user_bug12812@localhost|
drop function bug12812|
+create database db_bug14834;
+create user user1_bug14834@localhost identified by '';
+grant all on `db\_bug14834`.* to user1_bug14834@localhost;
+create user user2_bug14834@localhost identified by '';
+grant all on `db\_bug14834`.* to user2_bug14834@localhost;
+create user user3_bug14834@localhost identified by '';
+grant all on `db__ug14834`.* to user3_bug14834@localhost;
+create procedure p_bug14834() select user(), current_user();
+call p_bug14834();
+user() current_user()
+user1_bug14834@localhost user1_bug14834@localhost
+call p_bug14834();
+user() current_user()
+user2_bug14834@localhost user1_bug14834@localhost
+call p_bug14834();
+user() current_user()
+user3_bug14834@localhost user1_bug14834@localhost
+drop user user1_bug14834@localhost;
+drop user user2_bug14834@localhost;
+drop user user3_bug14834@localhost;
+drop database db_bug14834;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index a025c0503cd..ea4420c8e70 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -1178,8 +1178,8 @@ drop view v2|
delete from t1 |
delete from t2 |
drop table t4|
-drop table if exists fac|
-create table fac (n int unsigned not null primary key, f bigint unsigned)|
+drop table if exists t3|
+create table t3 (n int unsigned not null primary key, f bigint unsigned)|
drop procedure if exists ifac|
create procedure ifac(n int unsigned)
begin
@@ -1189,13 +1189,13 @@ set n = 20; # bigint overflow otherwise
end if;
while i <= n do
begin
-insert into test.fac values (i, fac(i));
+insert into test.t3 values (i, fac(i));
set i = i + 1;
end;
end while;
end|
call ifac(20)|
-select * from fac|
+select * from t3|
n f
1 1
2 2
@@ -1217,7 +1217,7 @@ n f
18 6402373705728000
19 121645100408832000
20 2432902008176640000
-drop table fac|
+drop table t3|
show function status like '%f%'|
Db Name Type Definer Modified Created Security_type Comment
test fac FUNCTION root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
@@ -1225,12 +1225,12 @@ drop procedure ifac|
drop function fac|
show function status like '%f%'|
Db Name Type Definer Modified Created Security_type Comment
-drop table if exists primes|
-create table primes (
+drop table if exists t3|
+create table t3 (
i int unsigned not null primary key,
p bigint unsigned not null
)|
-insert into primes values
+insert into t3 values
( 0, 3), ( 1, 5), ( 2, 7), ( 3, 11), ( 4, 13),
( 5, 17), ( 6, 19), ( 7, 23), ( 8, 29), ( 9, 31),
(10, 37), (11, 41), (12, 43), (13, 47), (14, 53),
@@ -1253,7 +1253,7 @@ set b = b+200, s = 0;
else
begin
declare p bigint unsigned;
-select t.p into p from test.primes t where t.i = s;
+select t.p into p from test.t3 t where t.i = s;
if b+p > r then
set pp = 1;
leave again;
@@ -1278,7 +1278,7 @@ begin
declare pp bool default 0;
call opp(p, pp);
if pp then
-insert into test.primes values (i, p);
+insert into test.t3 values (i, p);
set i = i+1;
end if;
set p = p+2;
@@ -1299,7 +1299,7 @@ set b = b+200, s = 0;
else
begin
declare p bigint unsigned;
-select t.p into p from test.primes t where t.i = s;
+select t.p into p from test.t3 t where t.i = s;
if b+p > r then
set pp = 1;
leave again;
@@ -1318,47 +1318,47 @@ Db Name Type Definer Modified Created Security_type Comment
test ip PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
test opp PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
call ip(200)|
-select * from primes where i=45 or i=100 or i=199|
+select * from t3 where i=45 or i=100 or i=199|
i p
45 211
100 557
199 1229
-drop table primes|
+drop table t3|
drop procedure opp|
drop procedure ip|
show procedure status like '%p%'|
Db Name Type Definer Modified Created Security_type Comment
-drop table if exists fib|
-create table fib ( f bigint unsigned not null )|
+drop table if exists t3|
+create table t3 ( f bigint unsigned not null )|
drop procedure if exists fib|
create procedure fib(n int unsigned)
begin
if n > 1 then
begin
declare x, y bigint unsigned;
-declare c cursor for select f from fib order by f desc limit 2;
+declare c cursor for select f from t3 order by f desc limit 2;
open c;
fetch c into y;
fetch c into x;
close c;
-insert into fib values (x+y);
+insert into t3 values (x+y);
call fib(n-1);
end;
end if;
end|
set @@max_sp_recursion_depth= 20|
-insert into fib values (0), (1)|
+insert into t3 values (0), (1)|
call fib(3)|
-select * from fib order by f asc|
+select * from t3 order by f asc|
f
0
1
1
2
-delete from fib|
-insert into fib values (0), (1)|
-call fib(20)|
-select * from fib order by f asc|
+delete from t3|
+insert into t3 values (0), (1)|
+call fib(10)|
+select * from t3 order by f asc|
f
0
1
@@ -1371,17 +1371,7 @@ f
21
34
55
-89
-144
-233
-377
-610
-987
-1597
-2584
-4181
-6765
-drop table fib|
+drop table t3|
drop procedure fib|
set @@max_sp_recursion_depth= 0|
drop procedure if exists bar|
diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result
index 8f2bd9985fc..e9289cf01c7 100644
--- a/mysql-test/r/sp_trans.result
+++ b/mysql-test/r/sp_trans.result
@@ -1,4 +1,4 @@
-drop table if exists t1, t2;
+drop table if exists t1, t2, t3;
drop procedure if exists bug8850|
create table t1 (a int) engine=innodb|
create procedure bug8850()
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 6094d23b0d0..85976c211c5 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -215,9 +215,9 @@ select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from
a
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
-8 7.5000
-8 4.5000
-9 7.5000
+8 7.5
+8 4.5
+9 7.5
explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t4 ALL NULL NULL NULL NULL 3
diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
index 5f801ee71c5..bed5a2d4903 100644
--- a/mysql-test/r/system_mysql_db.result
+++ b/mysql-test/r/system_mysql_db.result
@@ -46,6 +46,7 @@ db CREATE TABLE `db` (
`Alter_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Execute_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Event_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
+ `Trigger_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
PRIMARY KEY (`Host`,`Db`,`User`),
KEY `User` (`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Database privileges'
@@ -71,6 +72,7 @@ host CREATE TABLE `host` (
`Create_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Alter_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Execute_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
+ `Trigger_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
PRIMARY KEY (`Host`,`Db`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Host privileges; Merged with database privileges'
show create table user;
@@ -106,6 +108,7 @@ user CREATE TABLE `user` (
`Alter_routine_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Create_user_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`Event_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
+ `Trigger_priv` enum('N','Y') character set utf8 NOT NULL default 'N',
`ssl_type` enum('','ANY','X509','SPECIFIED') character set utf8 NOT NULL default '',
`ssl_cipher` blob NOT NULL,
`x509_issuer` blob NOT NULL,
@@ -134,7 +137,7 @@ tables_priv CREATE TABLE `tables_priv` (
`Table_name` char(64) collate utf8_bin NOT NULL default '',
`Grantor` char(77) collate utf8_bin NOT NULL default '',
`Timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
- `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') character set utf8 NOT NULL default '',
+ `Table_priv` set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') character set utf8 NOT NULL default '',
`Column_priv` set('Select','Insert','Update','References') character set utf8 NOT NULL default '',
PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`),
KEY `Grantor` (`Grantor`)
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index 352dd55653b..1e5373ba766 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -240,6 +240,28 @@ t3 CREATE TABLE `t3` (
`d` double(22,9) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2, t3;
+create table t1 select 105213674794682365.00 + 0.0 x;
+show warnings;
+Level Code Message
+desc t1;
+Field Type Null Key Default Extra
+x decimal(21,2) unsigned NO 0.00
+drop table t1;
+create table t1 select 0.0 x;
+desc t1;
+Field Type Null Key Default Extra
+x decimal(2,1) unsigned NO 0.0
+create table t2 select 105213674794682365.00 y;
+desc t2;
+Field Type Null Key Default Extra
+y decimal(20,2) unsigned NO 0.00
+create table t3 select x+y a from t1,t2;
+show warnings;
+Level Code Message
+desc t3;
+Field Type Null Key Default Extra
+a decimal(21,2) unsigned NO 0.00
+drop table t1,t2,t3;
create table t1 (s1 float(0,2));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
create table t1 (s1 float(1,2));
diff --git a/mysql-test/r/type_varchar.result b/mysql-test/r/type_varchar.result
index e3b12cc36e3..e74850bba33 100644
--- a/mysql-test/r/type_varchar.result
+++ b/mysql-test/r/type_varchar.result
@@ -415,3 +415,10 @@ t1 CREATE TABLE `t1` (
KEY `index1` (`f1`(10))
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(f1 VARCHAR(100) DEFAULT 'test');
+INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3));
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(f1 CHAR(100) DEFAULT 'test');
+INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3));
+DROP TABLE IF EXISTS t1;
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 4007fdf406e..dbb66e8e5cc 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -29,8 +29,6 @@ rpl_sp : Bug #16456
ndb_autodiscover : Needs to be fixed w.r.t binlog
ndb_autodiscover2 : Needs to be fixed w.r.t binlog
ndb_blob : BLOB replication causes core in master1 (Pekka will fix)
-system_mysql_db : Needs fixing
-system_mysql_db_fix : Needs fixing
#ndb_alter_table_row : sometimes wrong error 1015!=1046
ndb_gis : garbled msgs from corrupt THD*
ndb_binlog_ddl_multi : Bug #17038
diff --git a/mysql-test/t/fulltext2.test b/mysql-test/t/fulltext2.test
index 7a7b572d58f..fd97f795534 100644
--- a/mysql-test/t/fulltext2.test
+++ b/mysql-test/t/fulltext2.test
@@ -209,6 +209,14 @@ insert into t1 values('test test '),('test'),('test'),('test'),
('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test'),
('test'),('test'),('test'),('test'),('test'),('test'),('test'),('test');
delete from t1 limit 1;
+
+#
+# BUG#16489: utf8 + fulltext leads to corrupt index file.
+#
+truncate table t1;
+insert into t1 values('ab c d');
+update t1 set a='ab c d';
+select * from t1 where match a against('ab c' in boolean mode);
drop table t1;
set names latin1;
diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
index 24dd18daab1..9cf0ee452cd 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -121,7 +121,9 @@ drop table t1;
#
# InnoDB is required to reproduce the fault, but it is okay if we default to
# MyISAM when testing.
+--disable_warnings
create table t1 (a varchar(90), ts datetime not null, index (a)) engine=innodb default charset=utf8;
+--enable_warnings
insert into t1 values ('http://www.foo.com/', now());
select a from t1 where a='http://www.foo.com/' order by abs(timediff(ts, 0));
drop table t1;
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 7f61b4f080a..36374683e24 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -794,6 +794,29 @@ DROP TABLE t1;
DROP VIEW v1;
DROP FUNCTION func1;
DROP FUNCTION func2;
+
+#
+# Bug #15851 Unlistable directories yield no info from information_schema
+#
+create database mysqltest;
+create table mysqltest.t1(a int);
+--exec chmod -r $MYSQL_TEST_DIR/var/master-data/mysqltest
+select table_schema from information_schema.tables where table_schema='mysqltest';
+--exec chmod +r $MYSQL_TEST_DIR/var/master-data/mysqltest
+drop database mysqltest;
+
+#
+# Bug#15307 GROUP_CONCAT() with ORDER BY returns empty set on information_schema
+#
+select column_type, group_concat(table_schema, '.', table_name), count(*) as num
+from information_schema.columns where
+table_schema='information_schema' and
+(column_type = 'varchar(7)' or column_type = 'varchar(20)')
+group by column_type order by num;
+
+#
+# End of 5.0 tests.
+#
# Show engines
#
diff --git a/mysql-test/t/rpl_multi_update4-slave.opt b/mysql-test/t/rpl_multi_update4-slave.opt
new file mode 100644
index 00000000000..fea27db43ee
--- /dev/null
+++ b/mysql-test/t/rpl_multi_update4-slave.opt
@@ -0,0 +1 @@
+--replicate-wild-do-table=d1.%
diff --git a/mysql-test/t/rpl_multi_update4.test b/mysql-test/t/rpl_multi_update4.test
new file mode 100644
index 00000000000..3d909b8e5cd
--- /dev/null
+++ b/mysql-test/t/rpl_multi_update4.test
@@ -0,0 +1,44 @@
+# Let's verify that multi-update is not always skipped by slave if
+# some replicate-* rules exist.
+# (BUG#15699)
+
+source include/master-slave.inc;
+
+### Clean-up
+
+connection master;
+--disable_warnings
+drop database if exists d1;
+drop database if exists d2;
+
+connection slave;
+drop database if exists d2;
+--enable_warnings
+
+### Test
+
+connection master;
+create database d1; # accepted by slave
+create table d1.t0 (id int);
+create database d2; # ignored by slave
+use d2;
+create table t1 (id int);
+create table t2 (id int);
+insert into t1 values (1), (2), (3), (4), (5);
+insert into t2 select id + 3 from t1;
+# a problematic query which must be filter out by slave
+update t1 join t2 using (id) set t1.id = 0;
+insert into d1.t0 values (0); # replication works
+
+sync_slave_with_master;
+use d1;
+#connection slave;
+select * from t0 where id=0; # must find
+
+### Clean-up
+connection master;
+drop database d1;
+drop database d2;
+
+
+# End of test
diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test
index 64f99f3d8b9..708a3e0acaa 100644
--- a/mysql-test/t/rpl_sp.test
+++ b/mysql-test/t/rpl_sp.test
@@ -403,6 +403,42 @@ sync_slave_with_master;
connection slave;
select * from t1;
+#
+# Bug#16621 "INSERTs in Stored Procedures causes data corruption in the Binary
+# Log for 5.0.18"
+#
+
+# Prepare environment.
+
+connection master;
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# Test case.
+
+CREATE TABLE t1(col VARCHAR(10));
+
+CREATE PROCEDURE p1(arg VARCHAR(10))
+ INSERT INTO t1 VALUES(arg);
+
+CALL p1('test');
+
+SELECT * FROM t1;
+
+sync_slave_with_master;
+connection slave;
+
+SELECT * FROM t1;
+
+# Cleanup.
+
+connection master;
+
+DROP PROCEDURE p1;
+
# cleanup
connection master;
drop table t1;
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index cabd00fe5f9..d7044bee632 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -1534,6 +1534,7 @@ drop procedure bug13012_1|
drop function bug13012_2|
delimiter ;|
+#
# BUG#11555 "Stored procedures: current SP tables locking make
# impossible view security". We should not expose names of tables
# which are implicitly used by view (via stored routines/triggers).
@@ -1594,7 +1595,33 @@ drop function bug11555_1;
drop table t1;
drop view v1;
+#
+# BUG#15658: Server crashes after creating function as empty string
+#
+--disable_warnings
+drop procedure if exists ` bug15658`;
+--enable_warnings
+
+--error ER_SP_WRONG_NAME
+create procedure ``() select 1;
+--error ER_SP_WRONG_NAME
+create procedure ` `() select 1;
+--error ER_SP_WRONG_NAME
+create procedure `bug15658 `() select 1;
+--error ER_WRONG_DB_NAME
+create procedure ``.bug15658() select 1;
+--error ER_WRONG_DB_NAME
+create procedure `x `.bug15658() select 1;
+# This should work
+create procedure ` bug15658`() select 1;
+call ` bug15658`();
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status;
+drop procedure ` bug15658`;
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test
index 8d4f99abd71..0b24881a056 100644
--- a/mysql-test/t/sp-security.test
+++ b/mysql-test/t/sp-security.test
@@ -437,4 +437,48 @@ disconnect test_user_12812|
DROP USER user_bug12812@localhost|
drop function bug12812|
delimiter ;|
+
+
+#
+# BUG#14834: Server denies to execute Stored Procedure
+#
+# The problem here was with '_' in the database name.
+#
+create database db_bug14834;
+
+create user user1_bug14834@localhost identified by '';
+# The exact name of the database (no wildcard)
+grant all on `db\_bug14834`.* to user1_bug14834@localhost;
+
+create user user2_bug14834@localhost identified by '';
+# The exact name of the database (no wildcard)
+grant all on `db\_bug14834`.* to user2_bug14834@localhost;
+
+create user user3_bug14834@localhost identified by '';
+# Wildcards in the database name
+grant all on `db__ug14834`.* to user3_bug14834@localhost;
+
+connect (user1_bug14834,localhost,user1_bug14834,,db_bug14834);
+# Create the procedure and check that we can call it
+create procedure p_bug14834() select user(), current_user();
+call p_bug14834();
+
+connect (user2_bug14834,localhost,user2_bug14834,,db_bug14834);
+# This didn't work before
+call p_bug14834();
+
+connect (user3_bug14834,localhost,user3_bug14834,,db_bug14834);
+# Should also work
+call p_bug14834();
+
+# Cleanup
+connection default;
+disconnect user1_bug14834;
+disconnect user2_bug14834;
+disconnect user3_bug14834;
+drop user user1_bug14834@localhost;
+drop user user2_bug14834@localhost;
+drop user user3_bug14834@localhost;
+drop database db_bug14834;
+
# End of 5.0 bugs.
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 836d24340ef..02772313d01 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -1419,9 +1419,9 @@ drop table t4|
# fac
--disable_warnings
-drop table if exists fac|
+drop table if exists t3|
--enable_warnings
-create table fac (n int unsigned not null primary key, f bigint unsigned)|
+create table t3 (n int unsigned not null primary key, f bigint unsigned)|
--disable_warnings
drop procedure if exists ifac|
@@ -1435,15 +1435,15 @@ begin
end if;
while i <= n do
begin
- insert into test.fac values (i, fac(i));
+ insert into test.t3 values (i, fac(i));
set i = i + 1;
end;
end while;
end|
call ifac(20)|
-select * from fac|
-drop table fac|
+select * from t3|
+drop table t3|
--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show function status like '%f%'|
drop procedure ifac|
@@ -1455,15 +1455,15 @@ show function status like '%f%'|
# primes
--disable_warnings
-drop table if exists primes|
+drop table if exists t3|
--enable_warnings
-create table primes (
+create table t3 (
i int unsigned not null primary key,
p bigint unsigned not null
)|
-insert into primes values
+insert into t3 values
( 0, 3), ( 1, 5), ( 2, 7), ( 3, 11), ( 4, 13),
( 5, 17), ( 6, 19), ( 7, 23), ( 8, 29), ( 9, 31),
(10, 37), (11, 41), (12, 43), (13, 47), (14, 53),
@@ -1492,7 +1492,7 @@ begin
begin
declare p bigint unsigned;
- select t.p into p from test.primes t where t.i = s;
+ select t.p into p from test.t3 t where t.i = s;
if b+p > r then
set pp = 1;
leave again;
@@ -1523,7 +1523,7 @@ begin
call opp(p, pp);
if pp then
- insert into test.primes values (i, p);
+ insert into test.t3 values (i, p);
set i = i+1;
end if;
set p = p+2;
@@ -1545,8 +1545,8 @@ call ip(200)|
# 45 211
# 100 557
# 199 1229
-select * from primes where i=45 or i=100 or i=199|
-drop table primes|
+select * from t3 where i=45 or i=100 or i=199|
+drop table t3|
drop procedure opp|
drop procedure ip|
--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
@@ -1556,9 +1556,9 @@ show procedure status like '%p%'|
# Fibonacci, for recursion test. (Yet Another Numerical series :)
#
--disable_warnings
-drop table if exists fib|
+drop table if exists t3|
--enable_warnings
-create table fib ( f bigint unsigned not null )|
+create table t3 ( f bigint unsigned not null )|
# We deliberately do it the awkward way, fetching the last two
# values from the table, in order to exercise various statements
@@ -1571,13 +1571,13 @@ begin
if n > 1 then
begin
declare x, y bigint unsigned;
- declare c cursor for select f from fib order by f desc limit 2;
+ declare c cursor for select f from t3 order by f desc limit 2;
open c;
fetch c into y;
fetch c into x;
close c;
- insert into fib values (x+y);
+ insert into t3 values (x+y);
call fib(n-1);
end;
end if;
@@ -1588,22 +1588,23 @@ set @@max_sp_recursion_depth= 20|
# Minimum test: recursion of 3 levels
-insert into fib values (0), (1)|
+insert into t3 values (0), (1)|
call fib(3)|
-select * from fib order by f asc|
+select * from t3 order by f asc|
-delete from fib|
+delete from t3|
-# Original test: 20 levels (may run into memory limits!)
+# The original test, 20 levels, ran into memory limits on some machines
+# and builds. Try 10 instead...
-insert into fib values (0), (1)|
+insert into t3 values (0), (1)|
-call fib(20)|
+call fib(10)|
-select * from fib order by f asc|
-drop table fib|
+select * from t3 order by f asc|
+drop table t3|
drop procedure fib|
set @@max_sp_recursion_depth= 0|
diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test
index 308d4ad5c33..b9bd4c938b3 100644
--- a/mysql-test/t/sp_trans.test
+++ b/mysql-test/t/sp_trans.test
@@ -5,7 +5,7 @@
-- source include/have_innodb.inc
--disable_warnings
-drop table if exists t1, t2;
+drop table if exists t1, t2, t3;
--enable_warnings
delimiter |;
diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test
index 6a0814ef113..79f29624e89 100644
--- a/mysql-test/t/type_float.test
+++ b/mysql-test/t/type_float.test
@@ -159,6 +159,23 @@ show create table t3;
drop table t1, t2, t3;
+#
+# Bug #9855 (inconsistent column type for create select
+#
+create table t1 select 105213674794682365.00 + 0.0 x;
+show warnings;
+desc t1;
+drop table t1;
+
+create table t1 select 0.0 x;
+desc t1;
+create table t2 select 105213674794682365.00 y;
+desc t2;
+create table t3 select x+y a from t1,t2;
+show warnings;
+desc t3;
+drop table t1,t2,t3;
+
# End of 4.1 tests
#
diff --git a/mysql-test/t/type_varchar.test b/mysql-test/t/type_varchar.test
index 1a3a93018a4..2d2314f0a29 100644
--- a/mysql-test/t/type_varchar.test
+++ b/mysql-test/t/type_varchar.test
@@ -130,3 +130,19 @@ show create table t1;
alter table t1 modify f1 tinytext;
show create table t1;
drop table t1;
+
+#
+# BUG#15588: String overrun
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1(f1 VARCHAR(100) DEFAULT 'test');
+INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3));
+DROP TABLE IF EXISTS t1;
+
+CREATE TABLE t1(f1 CHAR(100) DEFAULT 'test');
+INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3));
+DROP TABLE IF EXISTS t1;
diff --git a/mysys/default_modify.c b/mysys/default_modify.c
index de03d783c68..0f58b8a930c 100644
--- a/mysys/default_modify.c
+++ b/mysys/default_modify.c
@@ -197,7 +197,7 @@ int modify_defaults_file(const char *file_location, const char *option,
goto err;
}
if (my_fclose(cnf_file, MYF(MY_WME)))
- goto err;
+ DBUG_RETURN(1);
my_free(file_buffer, MYF(0));
DBUG_RETURN(0);
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
index 1f3db84304e..e181ccfb88d 100644
--- a/mysys/mf_iocache2.c
+++ b/mysys/mf_iocache2.c
@@ -79,7 +79,7 @@ my_off_t my_b_safe_tell(IO_CACHE *info)
void my_b_seek(IO_CACHE *info,my_off_t pos)
{
- my_off_t offset;
+ my_off_t offset;
DBUG_ENTER("my_b_seek");
DBUG_PRINT("enter",("pos: %lu", (ulong) pos));
@@ -91,10 +91,10 @@ void my_b_seek(IO_CACHE *info,my_off_t pos)
b) see if there is a better way to make it work
*/
if (info->type == SEQ_READ_APPEND)
- flush_io_cache(info);
-
+ VOID(flush_io_cache(info));
+
offset=(pos - info->pos_in_file);
-
+
if (info->type == READ_CACHE || info->type == SEQ_READ_APPEND)
{
/* TODO: explain why this works if pos < info->pos_in_file */
@@ -119,7 +119,7 @@ void my_b_seek(IO_CACHE *info,my_off_t pos)
info->write_pos = info->write_buffer + offset;
DBUG_VOID_RETURN;
}
- flush_io_cache(info);
+ VOID(flush_io_cache(info));
/* Correct buffer end so that we write in increments of IO_SIZE */
info->write_end=(info->write_buffer+info->buffer_length-
(pos & (IO_SIZE-1)));
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index b4865557d80..91575d66368 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -114,7 +114,7 @@ my_bool bitmap_init(MY_BITMAP *map, uint32 *buf, uint n_bits,
#endif
;
if (!(buf= (uint32*) my_malloc(size_in_bytes, MYF(MY_WME))))
- return 1;
+ DBUG_RETURN(1);
}
#ifdef THREAD
else
diff --git a/mysys/my_error.c b/mysys/my_error.c
index 0c18bbf6e8b..d7177e7a047 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -189,7 +189,10 @@ int my_error_register(const char **errmsgs, int first, int last)
/* Error numbers must be unique. No overlapping is allowed. */
if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last))
+ {
+ my_free((gptr)meh_p, MYF(0));
return 1;
+ }
/* Insert header into the chain. */
meh_p->meh_next= *search_meh_pp;
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index 1908c70f407..4ca343064d3 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -170,6 +170,8 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
bzero(finfo.mystat, sizeof(MY_STAT));
VOID(strmov(tmp_file,dp->d_name));
VOID(my_stat(tmp_path, finfo.mystat, MyFlags));
+ if (!(finfo.mystat->st_mode & MY_S_IREAD))
+ continue;
}
else
finfo.mystat= NULL;
diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql
index 73b4ce32640..0fbaf7bec8a 100644
--- a/scripts/mysql_fix_privilege_tables.sql
+++ b/scripts/mysql_fix_privilege_tables.sql
@@ -674,5 +674,9 @@ ALTER TABLE event ADD sql_mode
SET @hadTriggerPriv := 0;
SELECT @hadTriggerPriv :=1 FROM user WHERE Trigger_priv LIKE '%';
-ALTER TABLE user add Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
+ALTER TABLE user ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL AFTER Event_priv;
+ALTER TABLE host ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
+ALTER TABLE db ADD Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL;
+ALTER TABLE tables_priv MODIFY Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger') COLLATE utf8_general_ci DEFAULT '' NOT NULL;
+
UPDATE user SET Trigger_priv=Super_priv WHERE @hadTriggerPriv = 0;
diff --git a/server-tools/instance-manager/parse.cc b/server-tools/instance-manager/parse.cc
index d83af2b9cf0..a79a6ad6742 100644
--- a/server-tools/instance-manager/parse.cc
+++ b/server-tools/instance-manager/parse.cc
@@ -107,7 +107,7 @@ Token shift_token(const char **text, uint *word_len)
int get_text_id(const char **text, uint *word_len, const char **id)
{
get_word(text, word_len);
- if (word_len == 0)
+ if (*word_len == 0)
return 1;
*id= *text;
return 0;
diff --git a/sql-common/client.c b/sql-common/client.c
index 5d0370d950a..2d826df0662 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -599,7 +599,7 @@ net_safe_read(MYSQL *mysql)
DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d",
vio_description(net->vio),len));
#ifdef MYSQL_SERVER
- if (vio_was_interrupted(net->vio))
+ if (net->vio && vio_was_interrupted(net->vio))
return (packet_error);
#endif /*MYSQL_SERVER*/
end_server(mysql);
diff --git a/sql/field.cc b/sql/field.cc
index 37cab37f7d2..3d983bb4d12 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1565,7 +1565,6 @@ Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table,
bool Field::quote_data(String *unquoted_string)
{
char escaped_string[IO_SIZE];
- char *unquoted_string_buffer= (char *)(unquoted_string->ptr());
DBUG_ENTER("Field::quote_data");
if (!needs_quotes())
@@ -4545,8 +4544,6 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
error= 1;
}
}
- if (error > 1)
- error= 2;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
@@ -5880,7 +5877,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
field_length/
field_charset->mbmaxlen,
&well_formed_error);
- memcpy(ptr,from,copy_length);
+ memmove(ptr, from, copy_length);
/* Append spaces if the string was shorter than the field. */
if (copy_length < field_length)
@@ -6296,7 +6293,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
field_length/
field_charset->mbmaxlen,
&well_formed_error);
- memcpy(ptr + length_bytes, from, copy_length);
+ memmove(ptr + length_bytes, from, copy_length);
if (length_bytes == 1)
*ptr= (uchar) copy_length;
else
@@ -7113,7 +7110,7 @@ void Field_blob::get_key_image(char *buff, uint length, imagetype type)
}
get_ptr(&blob);
gobj= Geometry::construct(&buffer, blob, blob_length);
- if (gobj->get_mbr(&mbr, &dummy))
+ if (!gobj || gobj->get_mbr(&mbr, &dummy))
bzero(buff, SIZEOF_STORED_DOUBLE*4);
else
{
@@ -7442,7 +7439,7 @@ void Field_geom::get_key_image(char *buff, uint length, imagetype type)
}
get_ptr(&blob);
gobj= Geometry::construct(&buffer, blob, blob_length);
- if (gobj->get_mbr(&mbr, &dummy))
+ if (!gobj || gobj->get_mbr(&mbr, &dummy))
bzero(buff, SIZEOF_STORED_DOUBLE*4);
else
{
@@ -8239,16 +8236,13 @@ const char *Field_bit::unpack(char *to, const char *from)
*/
Field_bit_as_char::Field_bit_as_char(char *ptr_arg, uint32 len_arg,
- uchar *null_ptr_arg, uchar null_bit_arg,
- uchar *bit_ptr_arg, uchar bit_ofs_arg,
- enum utype unireg_check_arg,
+ uchar *null_ptr_arg, uchar null_bit_arg,
+ enum utype unireg_check_arg,
const char *field_name_arg)
- :Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, bit_ptr_arg,
- bit_ofs_arg, unireg_check_arg, field_name_arg),
+ :Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 0, 0,
+ unireg_check_arg, field_name_arg),
create_length(len_arg)
{
- bit_ptr= 0;
- bit_ofs= 0;
bit_len= 0;
field_length= ((len_arg + 7) & ~7) / 8;
}
@@ -8950,10 +8944,10 @@ Field *make_field(TABLE_SHARE *share, char *ptr, uint32 field_length,
field_charset);
case FIELD_TYPE_BIT:
return f_bit_as_char(pack_flag) ?
- new Field_bit_as_char(ptr, field_length, null_pos, null_bit,
- bit_ptr, bit_offset, unireg_check, field_name) :
- new Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr,
- bit_offset, unireg_check, field_name);
+ new Field_bit_as_char(ptr, field_length, null_pos, null_bit,
+ unireg_check, field_name) :
+ new Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr,
+ bit_offset, unireg_check, field_name);
default: // Impossible (Wrong version)
break;
diff --git a/sql/field.h b/sql/field.h
index 806d0c3328a..15c54f65ef7 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1373,12 +1373,12 @@ public:
}
};
-
+
class Field_bit_as_char: public Field_bit {
public:
uchar create_length;
Field_bit_as_char(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
- uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg,
+ uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg);
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
uint32 max_length() { return (uint32) create_length; }
diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc
index 65049bac135..2a2ac475c0b 100644
--- a/sql/ha_archive.cc
+++ b/sql/ha_archive.cc
@@ -139,6 +139,10 @@ static HASH archive_open_tables;
/* Static declarations for handerton */
static handler *archive_create_handler(TABLE_SHARE *table);
+/*
+ Number of rows that will force a bulk insert.
+*/
+#define ARCHIVE_MIN_ROWS_TO_USE_BULK_INSERT 2
/* dummy handlerton - only to have something to return from archive_db_init */
@@ -1302,7 +1306,8 @@ void ha_archive::info(uint flag)
void ha_archive::start_bulk_insert(ha_rows rows)
{
DBUG_ENTER("ha_archive::start_bulk_insert");
- bulk_insert= TRUE;
+ if (!rows || rows >= ARCHIVE_MIN_ROWS_TO_USE_BULK_INSERT)
+ bulk_insert= TRUE;
DBUG_VOID_RETURN;
}
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 2e785f13ea3..5f0adba6e8c 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -286,7 +286,8 @@ int ha_myisam::dump(THD* thd, int fd)
if (fd < 0)
{
- my_net_write(net, "", 0);
+ if (my_net_write(net, "", 0))
+ error = errno ? errno : EPIPE;
net_flush(net);
}
@@ -420,12 +421,14 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
{
uint old_testflag=param.testflag;
param.testflag|=T_MEDIUM;
- init_io_cache(&param.read_cache, file->dfile,
- my_default_record_cache_size, READ_CACHE,
- share->pack.header_length, 1, MYF(MY_WME));
- error |= chk_data_link(&param, file, param.testflag & T_EXTEND);
- end_io_cache(&(param.read_cache));
- param.testflag=old_testflag;
+ if (!(error= init_io_cache(&param.read_cache, file->dfile,
+ my_default_record_cache_size, READ_CACHE,
+ share->pack.header_length, 1, MYF(MY_WME))))
+ {
+ error= chk_data_link(&param, file, param.testflag & T_EXTEND);
+ end_io_cache(&(param.read_cache));
+ }
+ param.testflag= old_testflag;
}
}
if (!error)
diff --git a/sql/item.cc b/sql/item.cc
index fa5c2b5cc3b..6c410a3b8bd 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -985,7 +985,7 @@ Item_case_expr::this_item_addr(THD *thd, Item **)
void Item_case_expr::print(String *str)
{
- str->append(STRING_WITH_LEN("case_expr@"));
+ VOID(str->append(STRING_WITH_LEN("case_expr@")));
str->qs_append(m_case_expr_id);
}
@@ -3868,7 +3868,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
name);
break;
case MYSQL_TYPE_BIT:
- field= new Field_bit_as_char(NULL, max_length, null_ptr, 0, NULL, 0,
+ field= new Field_bit_as_char(NULL, max_length, null_ptr, 0,
Field::NONE, name);
break;
default:
diff --git a/sql/item_func.cc b/sql/item_func.cc
index c4c03e1cbf2..60b0dafefc5 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -431,12 +431,19 @@ my_decimal *Item_real_func::val_decimal(my_decimal *decimal_value)
void Item_func::fix_num_length_and_dec()
{
- decimals= 0;
+ uint fl_length= 0;
+ decimals=0;
for (uint i=0 ; i < arg_count ; i++)
{
- set_if_bigger(decimals, args[i]->decimals);
+ set_if_bigger(decimals,args[i]->decimals);
+ set_if_bigger(fl_length, args[i]->max_length);
+ }
+ max_length=float_length(decimals);
+ if (fl_length > max_length)
+ {
+ decimals= NOT_FIXED_DEC;
+ max_length= float_length(NOT_FIXED_DEC);
}
- max_length= float_length(decimals);
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 15eb4c3aaf0..64a692d394d 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -3342,6 +3342,10 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
case INSERT_ID_EVENT:
msg="INSERT_ID";
break;
+ case INVALID_INT_EVENT:
+ default: // cannot happen
+ msg="INVALID_INT";
+ break;
}
fprintf(file, "%s=%s;\n", msg, llstr(val,llbuff));
fflush(file);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 5ae0295d427..be476c11533 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5130,7 +5130,7 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
"Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second).",
(gptr*) &innobase_flush_log_at_trx_commit,
(gptr*) &innobase_flush_log_at_trx_commit,
- 0, GET_UINT, OPT_ARG, 1, 0, 2, 0, 0, 0},
+ 0, GET_ULONG, OPT_ARG, 1, 0, 2, 0, 0, 0},
{"innodb_flush_method", OPT_INNODB_FLUSH_METHOD,
"With which method to flush data.", (gptr*) &innobase_unix_file_flush_method,
(gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 9e20fa28239..887690aecc1 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -753,7 +753,6 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
table_map read_tables, COND *conds,
bool allow_null_cond,
int *error)
-
{
SQL_SELECT *select;
DBUG_ENTER("make_select");
@@ -7059,10 +7058,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
if (!quick)
return 0; /* no ranges found */
if (quick->init())
- {
- delete quick;
goto err;
- }
quick->records= records;
if (cp_buffer_from_ref(thd,ref) && thd->is_fatal_error ||
@@ -8404,7 +8400,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
ha_rows cur_records;
SEL_ARG *cur_index_tree= NULL;
ha_rows cur_quick_prefix_records= 0;
- uint cur_param_idx;
+ uint cur_param_idx=MAX_KEY;
key_map cur_used_key_parts;
uint pk= param->table->s->primary_key;
@@ -8620,6 +8616,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
*/
if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost))
{
+ DBUG_ASSERT(tree != 0 || cur_param_idx == MAX_KEY);
index_info= cur_index_info;
index= cur_index;
best_read_cost= cur_read_cost;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index a27b3607d73..bc2496b0769 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -706,7 +706,7 @@ class SQL_SELECT :public Sql_alloc {
class FT_SELECT: public QUICK_RANGE_SELECT {
public:
FT_SELECT(THD *thd, TABLE *table, uint key) :
- QUICK_RANGE_SELECT (thd, table, key, 1) { init(); }
+ QUICK_RANGE_SELECT (thd, table, key, 1) { VOID(init()); }
~FT_SELECT() { file->ft_end(); }
int init() { return error=file->ft_init(); }
int reset() { return 0; }
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 98cded56871..650bd8fc58f 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -601,9 +601,23 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
else
{
/* With conversion */
+ uint max_char_len;
int2store(pos, thd_charset->number);
- uint char_len= field.length / item->collation.collation->mbmaxlen;
- int4store(pos+2, char_len * thd_charset->mbmaxlen);
+ /*
+ For TEXT/BLOB columns, field_length describes the maximum data
+ length in bytes. There is no limit to the number of characters
+ that a TEXT column can store, as long as the data fits into
+ the designated space.
+ For the rest of textual columns, field_length is evaluated as
+ char_count * mbmaxlen, where character count is taken from the
+ definition of the column. In other words, the maximum number
+ of characters here is limited by the column definition.
+ */
+ max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB &&
+ field.type <= (int) MYSQL_TYPE_BLOB) ?
+ field.length / item->collation.collation->mbminlen :
+ field.length / item->collation.collation->mbmaxlen;
+ int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
}
pos[6]= field.type;
int2store(pos+7,field.flags);
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 960e0ac86cc..34dcd80a236 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -930,7 +930,8 @@ bool load_master_data(THD* thd)
host was specified; there could have been a problem when replication
started, which led to relay log's IO_CACHE to not be inited.
*/
- flush_master_info(active_mi, 0);
+ if (flush_master_info(active_mi, 0))
+ sql_print_error("Failed to flush master info file");
}
mysql_free_result(master_status_res);
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index fd54d5a2916..a6c2fca7fc5 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -2496,7 +2496,6 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
bool sys_var_sync_binlog_period::update(THD *thd, set_var *var)
{
- pthread_mutex_t *lock_log= mysql_bin_log.get_log_lock();
sync_binlog_period= (ulong) var->save_result.ulonglong_value;
return 0;
}
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 084ab31c459..1099b410290 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5798,3 +5798,5 @@ ER_CANT_WRITE_LOCK_LOG_TABLE
eng "You can't write-lock a log table. Only read access is possible."
ER_CANT_READ_LOCK_LOG_TABLE
eng "You can't use usual read lock with log tables. Try READ LOCAL instead."
+ER_SP_WRONG_NAME 42000
+ eng "Incorrect routine name '%-.64s'"
diff --git a/sql/slave.cc b/sql/slave.cc
index edca614159a..763db31c05d 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1742,7 +1742,8 @@ static void write_ignored_events_info_to_relay_log(THD *thd, MASTER_INFO *mi)
" to the relay log, "
"SHOW SLAVE STATUS may be inaccurate");
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
- flush_master_info(mi, 1);
+ if (flush_master_info(mi, 1))
+ sql_print_error("Failed to flush master info file");
delete ev;
}
else
@@ -2233,7 +2234,7 @@ bool show_master_info(THD* thd, MASTER_INFO* mi)
pthread_mutex_unlock(&mi->rli.data_lock);
pthread_mutex_unlock(&mi->data_lock);
-
+
if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
DBUG_RETURN(TRUE);
}
@@ -2241,8 +2242,13 @@ bool show_master_info(THD* thd, MASTER_INFO* mi)
DBUG_RETURN(FALSE);
}
-
-bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
+/*
+ RETURN
+ 2 - flush relay log failed
+ 1 - flush master info failed
+ 0 - all ok
+*/
+int flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
{
IO_CACHE* file = &mi->file;
char lbuf[22];
@@ -2261,8 +2267,9 @@ bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
When we come to this place in code, relay log may or not be initialized;
the caller is responsible for setting 'flush_relay_log_cache' accordingly.
*/
- if (flush_relay_log_cache)
- flush_io_cache(mi->rli.relay_log.get_log_file());
+ if (flush_relay_log_cache &&
+ flush_io_cache(mi->rli.relay_log.get_log_file()))
+ DBUG_RETURN(2);
/*
We flushed the relay log BEFORE the master.info file, because if we crash
@@ -2274,13 +2281,13 @@ bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
*/
/*
- In certain cases this code may create master.info files that seems
- corrupted, because of extra lines filled with garbage in the end
- file (this happens if new contents take less space than previous
- contents of file). But because of number of lines in the first line
+ In certain cases this code may create master.info files that seems
+ corrupted, because of extra lines filled with garbage in the end
+ file (this happens if new contents take less space than previous
+ contents of file). But because of number of lines in the first line
of file we don't care about this garbage.
*/
-
+
my_b_seek(file, 0L);
my_b_printf(file, "%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n",
LINES_IN_MASTER_INFO_WITH_SSL,
@@ -2289,8 +2296,7 @@ bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
mi->password, mi->port, mi->connect_retry,
(int)(mi->ssl), mi->ssl_ca, mi->ssl_capath, mi->ssl_cert,
mi->ssl_cipher, mi->ssl_key);
- flush_io_cache(file);
- DBUG_RETURN(0);
+ DBUG_RETURN(-flush_io_cache(file));
}
@@ -3355,7 +3361,11 @@ reconnect done to recover from failed read");
sql_print_error("Slave I/O thread could not queue event from master");
goto err;
}
- flush_master_info(mi, 1); /* sure that we can flush the relay log */
+ if (flush_master_info(mi, 1))
+ {
+ sql_print_error("Failed to flush master info file");
+ goto err;
+ }
/*
See if the relay logs take too much space.
We don't lock mi->rli.log_space_lock here; this dirty read saves time
diff --git a/sql/slave.h b/sql/slave.h
index 6870aaca752..0b77d7f7c4f 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -231,7 +231,7 @@ int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
int init_slave();
void init_slave_skip_errors(const char* arg);
-bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache);
+int flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache);
bool flush_relay_log_info(RELAY_LOG_INFO* rli);
int register_slave_on_master(MYSQL* mysql);
int terminate_slave_threads(MASTER_INFO* mi, int thread_mask,
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index e1af0b7d939..e4e87eb5620 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -105,21 +105,27 @@ sp_get_item_value(Item *item, String *str)
case STRING_RESULT:
{
- char buf_holder[STRING_BUFFER_USUAL_SIZE];
- String buf(buf_holder, sizeof(buf_holder), &my_charset_latin1);
String *result= item->val_str(str);
if (!result)
return NULL;
- buf.append('_');
- buf.append(result->charset()->csname);
- buf.append('\'');
- buf.append(*result);
- buf.append('\'');
- str->copy(buf);
-
- return str;
+ {
+ char buf_holder[STRING_BUFFER_USUAL_SIZE];
+ String buf(buf_holder, sizeof(buf_holder), result->charset());
+
+ /* We must reset length of the buffer, because of String specificity. */
+ buf.length(0);
+
+ buf.append('_');
+ buf.append(result->charset()->csname);
+ buf.append('\'');
+ buf.append(*result);
+ buf.append('\'');
+ str->copy(buf);
+
+ return str;
+ }
}
case ROW_RESULT:
@@ -389,6 +395,23 @@ sp_name_current_db_new(THD *thd, LEX_STRING name)
return qname;
}
+/*
+ Check that the name 'ident' is ok. It's assumed to be an 'ident'
+ from the parser, so we only have to check length and trailing spaces.
+ The former is a standard requirement (and 'show status' assumes a
+ non-empty name), the latter is a mysql:ism as trailing spaces are
+ removed by get_field().
+
+ RETURN
+ TRUE - bad name
+ FALSE - name is ok
+*/
+
+bool
+check_routine_name(LEX_STRING ident)
+{
+ return (!ident.str || !ident.str[0] || ident.str[ident.length-1] == ' ');
+}
/* ------------------------------------------------------------------ */
@@ -3083,9 +3106,16 @@ sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
void
sp_instr_set_case_expr::print(String *str)
{
- str->append(STRING_WITH_LEN("set_case_expr "));
+ const char CASE_EXPR_TAG[]= "set_case_expr ";
+ const int CASE_EXPR_TAG_LEN= sizeof(CASE_EXPR_TAG) - 1;
+ const int INT_STRING_MAX_LEN= 10;
+
+ /* We must call reserve(), because qs_append() doesn't care about memory. */
+ str->reserve(CASE_EXPR_TAG_LEN + INT_STRING_MAX_LEN + 2);
+
+ str->qs_append(CASE_EXPR_TAG, CASE_EXPR_TAG_LEN);
str->qs_append(m_case_expr_id);
- str->append(' ');
+ str->qs_append(' ');
m_case_expr->print(str);
}
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 37ab486c6f3..c4b6cb36090 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -103,6 +103,8 @@ public:
sp_name *
sp_name_current_db_new(THD *thd, LEX_STRING name);
+bool
+check_routine_name(LEX_STRING name);
class sp_head :private Query_arena
{
diff --git a/sql/spatial.h b/sql/spatial.h
index 4253689c078..527dc750bdc 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -142,7 +142,7 @@ struct MBR
bool inner_point(double x, double y) const
{
/* The following should be safe, even if we compare doubles */
- return (xmin<x) && (xmax>x) && (ymin<y) && (ymax>x);
+ return (xmin<x) && (xmax>x) && (ymin<y) && (ymax>y);
}
int overlaps(const MBR *mbr)
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index dc56880a1a0..cfcdd6d9e61 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -951,7 +951,7 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', db: '%s'",
(host ? host : "(NULL)"), (ip ? ip : "(NULL)"),
- (user ? user : "(NULL)"), (db ? db : "(NULL)")));
+ user, (db ? db : "(NULL)")));
sctx->user= user;
sctx->host= host;
sctx->ip= ip;
@@ -980,7 +980,7 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
for (i=0 ; i < acl_users.elements ; i++)
{
acl_user= dynamic_element(&acl_users,i,ACL_USER*);
- if ((!acl_user->user && (!user || !user[0])) ||
+ if ((!acl_user->user && !user[0]) ||
(acl_user->user && strcmp(user, acl_user->user) == 0))
{
if (compare_hostname(&acl_user->host, host, ip))
@@ -1001,7 +1001,7 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
{
if (compare_hostname(&acl_db->host, host, ip))
{
- if (!acl_db->db || (db && !strcmp(acl_db->db, db)))
+ if (!acl_db->db || (db && !wild_compare(db, acl_db->db, 0)))
{
sctx->db_access= acl_db->access;
break;
@@ -4980,8 +4980,6 @@ static int handle_grant_struct(uint struct_no, bool drop,
}
if (! user)
user= "";
- if (! host)
- host= "";
#ifdef EXTRA_DEBUG
DBUG_PRINT("loop",("scan struct: %u index: %u user: '%s' host: '%s'",
struct_no, idx, user, host));
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 5ffa4fd76ed..e2e336eb891 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -287,7 +287,7 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
}
-/*
+/*
Load database options file
load_db_opt()
@@ -313,68 +313,72 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
bzero((char*) create,sizeof(*create));
create->default_table_charset= thd->variables.collation_server;
-
+
/* Check if options for this database are already in the hash */
if (!get_dbopt(path, create))
- DBUG_RETURN(0);
-
+ DBUG_RETURN(0);
+
/* Otherwise, load options from the .opt file */
- if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) >= 0)
- {
- IO_CACHE cache;
- init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0));
+ if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
+ goto err1;
- while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
+ IO_CACHE cache;
+ if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
+ goto err2;
+
+ while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
+ {
+ char *pos= buf+nbytes-1;
+ /* Remove end space and control characters */
+ while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
+ pos--;
+ *pos=0;
+ if ((pos= strchr(buf, '=')))
{
- char *pos= buf+nbytes-1;
- /* Remove end space and control characters */
- while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
- pos--;
- *pos=0;
- if ((pos= strchr(buf, '=')))
+ if (!strncmp(buf,"default-character-set", (pos-buf)))
{
- if (!strncmp(buf,"default-character-set", (pos-buf)))
- {
- /*
- Try character set name, and if it fails
- try collation name, probably it's an old
- 4.1.0 db.opt file, which didn't have
- separate default-character-set and
- default-collation commands.
- */
- if (!(create->default_table_charset=
- get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
- !(create->default_table_charset=
- get_charset_by_name(pos+1, MYF(0))))
- {
- sql_print_error("Error while loading database options: '%s':",path);
- sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
- create->default_table_charset= default_charset_info;
- }
- }
- else if (!strncmp(buf,"default-collation", (pos-buf)))
- {
- if (!(create->default_table_charset= get_charset_by_name(pos+1,
- MYF(0))))
- {
- sql_print_error("Error while loading database options: '%s':",path);
- sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1);
- create->default_table_charset= default_charset_info;
- }
- }
+ /*
+ Try character set name, and if it fails
+ try collation name, probably it's an old
+ 4.1.0 db.opt file, which didn't have
+ separate default-character-set and
+ default-collation commands.
+ */
+ if (!(create->default_table_charset=
+ get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
+ !(create->default_table_charset=
+ get_charset_by_name(pos+1, MYF(0))))
+ {
+ sql_print_error("Error while loading database options: '%s':",path);
+ sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
+ create->default_table_charset= default_charset_info;
+ }
+ }
+ else if (!strncmp(buf,"default-collation", (pos-buf)))
+ {
+ if (!(create->default_table_charset= get_charset_by_name(pos+1,
+ MYF(0))))
+ {
+ sql_print_error("Error while loading database options: '%s':",path);
+ sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1);
+ create->default_table_charset= default_charset_info;
+ }
}
}
- end_io_cache(&cache);
- my_close(file,MYF(0));
- /*
- Put the loaded value into the hash.
- Note that another thread could've added the same
- entry to the hash after we called get_dbopt(),
- but it's not an error, as put_dbopt() takes this
- possibility into account.
- */
- error= put_dbopt(path, create);
}
+ /*
+ Put the loaded value into the hash.
+ Note that another thread could've added the same
+ entry to the hash after we called get_dbopt(),
+ but it's not an error, as put_dbopt() takes this
+ possibility into account.
+ */
+ error= put_dbopt(path, create);
+
+ end_io_cache(&cache);
+err2:
+ my_close(file,MYF(0));
+err1:
DBUG_RETURN(error);
}
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 0715aeeaa5b..ea9bca57cc6 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -567,7 +567,7 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond,
SQL_SELECT *res= make_select(table, 0, 0, cond, 0, error);
if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) ||
- (res->quick && res->quick->reset()))
+ (res && res->quick && res->quick->reset()))
{
delete res;
res=0;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index a265d32e7c2..6655491ca57 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -686,7 +686,7 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view)
DBUG_ASSERT(view->table != 0 && view->field_translation != 0);
- bitmap_init(&used_fields, used_fields_buff, table->s->fields, 0);
+ VOID(bitmap_init(&used_fields, used_fields_buff, table->s->fields, 0));
bitmap_clear_all(&used_fields);
view->contain_auto_increment= 0;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ed7e7dfb684..279a02fa1d1 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1615,6 +1615,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
statistic_increment(thd->status_var.com_other, &LOCK_status);
thd->enable_slow_log= opt_log_slow_admin_statements;
db= thd->alloc(db_len + tbl_len + 2);
+ if (!db)
+ {
+ my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
+ break;
+ }
tbl_name= strmake(db, packet + 1, db_len)+1;
strmake(tbl_name, packet + db_len + 2, tbl_len);
mysql_table_dump(thd, db, tbl_name, -1);
@@ -1628,14 +1633,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
statistic_increment(thd->status_var.com_other, &LOCK_status);
char *user= (char*) packet;
char *passwd= strend(user)+1;
- /*
+ /*
Old clients send null-terminated string ('\0' for empty string) for
password. New clients send the size (1 byte) + string (not null
terminated, so also '\0' for empty string).
*/
- char db_buff[NAME_LEN+1]; // buffer to store db in utf8
+ char db_buff[NAME_LEN+1]; // buffer to store db in utf8
char *db= passwd;
- uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+ uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
*passwd++ : strlen(passwd);
db+= passwd_len + 1;
#ifndef EMBEDDED_LIBRARY
@@ -2414,23 +2419,26 @@ mysql_execute_command(THD *thd)
}
}
else
+ {
#endif /* HAVE_REPLICATION */
-
- /*
- When option readonly is set deny operations which change non-temporary
- tables. Except for the replication thread and the 'super' users.
- */
- if (opt_readonly &&
- !(thd->security_ctx->master_access & SUPER_ACL) &&
- uc_update_queries[lex->sql_command] &&
- !((lex->sql_command == SQLCOM_CREATE_TABLE) &&
- (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
- ((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
- some_non_temp_table_to_be_updated(thd, all_tables)))
- {
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
- DBUG_RETURN(-1);
- }
+ /*
+ When option readonly is set deny operations which change non-temporary
+ tables. Except for the replication thread and the 'super' users.
+ */
+ if (opt_readonly &&
+ !(thd->security_ctx->master_access & SUPER_ACL) &&
+ uc_update_queries[lex->sql_command] &&
+ !((lex->sql_command == SQLCOM_CREATE_TABLE) &&
+ (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
+ ((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
+ some_non_temp_table_to_be_updated(thd, all_tables)))
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
+ DBUG_RETURN(-1);
+ }
+#ifdef HAVE_REPLICATION
+ } /* endif unlikely slave */
+#endif
if(lex->orig_sql_command == SQLCOM_END)
statistic_increment(thd->status_var.com_stat[lex->sql_command],
&LOCK_status);
@@ -3226,8 +3234,7 @@ end_with_restore_list:
else
res= 0;
- if ((res= mysql_multi_update_prepare(thd)))
- break;
+ res= mysql_multi_update_prepare(thd);
#ifdef HAVE_REPLICATION
/* Check slave filtering rules */
@@ -3235,20 +3242,33 @@ end_with_restore_list:
{
if (all_tables_not_ok(thd, all_tables))
{
+ if (res!= 0)
+ {
+ res= 0; /* don't care of prev failure */
+ thd->clear_error(); /* filters are of highest prior */
+ }
/* we warn the slave SQL thread */
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
break;
}
+ if (res)
+ break;
}
else
-#endif /* HAVE_REPLICATION */
- if (opt_readonly &&
- !(thd->security_ctx->master_access & SUPER_ACL) &&
- some_non_temp_table_to_be_updated(thd, all_tables))
{
- my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
- break;
- }
+#endif /* HAVE_REPLICATION */
+ if (res)
+ break;
+ if (opt_readonly &&
+ !(thd->security_ctx->master_access & SUPER_ACL) &&
+ some_non_temp_table_to_be_updated(thd, all_tables))
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
+ break;
+ }
+#ifdef HAVE_REPLICATION
+ } /* unlikely */
+#endif
res= mysql_multi_update(thd, all_tables,
&select_lex->item_list,
@@ -6631,6 +6651,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
#ifdef HAVE_REPLICATION
if (options & REFRESH_MASTER)
{
+ DBUG_ASSERT(thd);
tmp_write_to_binlog= 0;
if (reset_master(thd))
{
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index b66e617c06e..cb080ba68e0 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2120,6 +2120,8 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
were closed in the end of previous prepare or execute call.
*/
tables->table= 0;
+ /* Reset is_schema_table_processed value(needed for I_S tables */
+ tables->is_schema_table_processed= FALSE;
if (tables->prep_on_expr)
{
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index ed056f62fe3..bf9a6078a8f 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1201,7 +1201,12 @@ bool change_master(THD* thd, MASTER_INFO* mi)
Relay log's IO_CACHE may not be inited, if rli->inited==0 (server was never
a slave before).
*/
- flush_master_info(mi, 0);
+ if (flush_master_info(mi, 0))
+ {
+ my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush master info file");
+ unlock_slave_threads(mi);
+ DBUG_RETURN(TRUE);
+ }
if (need_relay_log_purge)
{
relay_log_purge= 1;
@@ -1311,14 +1316,15 @@ bool mysql_show_binlog_events(THD* thd)
bool ret = TRUE;
IO_CACHE log;
File file = -1;
- Format_description_log_event *description_event= new
- Format_description_log_event(3); /* MySQL 4.0 by default */
Log_event::init_show_field_list(&field_list);
if (protocol->send_fields(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
+ Format_description_log_event *description_event= new
+ Format_description_log_event(3); /* MySQL 4.0 by default */
+
/*
Wait for handlers to insert any pending information
into the binlog. For e.g. ndb which updates the binlog asynchronously
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 47f970a4f82..47aa53d25e2 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9117,7 +9117,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
field++;
}
- *field= NULL; /* mark the end of the list */
+ *field= NULL; /* mark the end of the list */
share->blob_field[blob_count]= 0; /* mark the end of the list */
share->blob_fields= blob_count;
@@ -11659,6 +11659,12 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
goto err;
}
}
+
+ /* Fill schema tables with data before filesort if it's necessary */
+ if ((join->select_lex->options & OPTION_SCHEMA_TABLE) &&
+ get_schema_tables_result(join))
+ goto err;
+
if (table->s->tmp_table)
table->file->info(HA_STATUS_VARIABLE); // Get record count
table->sort.found_records=filesort(thd, table,sortorder, length,
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1e051ab34c4..d30ce8d6b59 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -781,7 +781,7 @@ append_identifier(THD *thd, String *packet, const char *name, uint length)
it's a keyword
*/
- packet->reserve(length*2 + 2);
+ VOID(packet->reserve(length*2 + 2));
quote_char= (char) q;
packet->append(&quote_char, 1, system_charset_info);
@@ -1097,13 +1097,13 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
if (key_part->field)
append_identifier(thd,packet,key_part->field->field_name,
strlen(key_part->field->field_name));
- if (!key_part->field ||
+ if (key_part->field &&
(key_part->length !=
table->field[key_part->fieldnr-1]->key_length() &&
!(key_info->flags & HA_FULLTEXT)))
{
buff[0] = '(';
- char* end=int10_to_str((long) key_part->length /
+ char* end=int10_to_str((long) key_part->length /
key_part->field->charset()->mbmaxlen,
buff + 1,10);
*end++ = ')';
@@ -1856,7 +1856,8 @@ LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
{
MEM_ROOT *mem= thd->mem_root;
if (allocate_lex_string)
- lex_str= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING));
+ if (!(lex_str= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING))))
+ return 0;
lex_str->str= strmake_root(mem, str, length);
lex_str->length= length;
return lex_str;
@@ -3115,7 +3116,7 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
/*
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
rather than in SHOW KEYS
- */
+ */
if (!tables->view)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
thd->net.last_errno, thd->net.last_error);
@@ -3128,7 +3129,7 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
{
TABLE *show_table= tables->table;
KEY *key_info=show_table->key_info;
- show_table->file->info(HA_STATUS_VARIABLE |
+ show_table->file->info(HA_STATUS_VARIABLE |
HA_STATUS_NO_LOCK |
HA_STATUS_TIME);
for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
@@ -3140,7 +3141,7 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
restore_record(table, s->default_values);
table->field[1]->store(base_name, strlen(base_name), cs);
table->field[2]->store(file_name, strlen(file_name), cs);
- table->field[3]->store((longlong) ((key_info->flags &
+ table->field[3]->store((longlong) ((key_info->flags &
HA_NOSAME) ? 0 : 1), TRUE);
table->field[4]->store(base_name, strlen(base_name), cs);
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
@@ -3163,12 +3164,12 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
table->field[9]->store((longlong) records, TRUE);
table->field[9]->set_notnull();
}
- if (!(key_info->flags & HA_FULLTEXT) &&
- (!key_part->field ||
- key_part->length !=
+ if (!(key_info->flags & HA_FULLTEXT) &&
+ (key_part->field &&
+ key_part->length !=
show_table->field[key_part->fieldnr-1]->key_length()))
{
- table->field[10]->store((longlong) key_part->length /
+ table->field[10]->store((longlong) key_part->length /
key_part->field->charset()->mbmaxlen);
table->field[10]->set_notnull();
}
@@ -4549,7 +4550,16 @@ bool get_schema_tables_result(JOIN *join)
TABLE_LIST *table_list= tab->table->pos_in_table_list;
if (table_list->schema_table && thd->fill_derived_tables())
{
- if (&lex->unit != lex->current_select->master_unit()) // is subselect
+ bool is_subselect= (&lex->unit != lex->current_select->master_unit());
+ /*
+ The schema table is already processed and
+ the statement is not a subselect.
+ So we don't need to handle this table again.
+ */
+ if (table_list->is_schema_table_processed && !is_subselect)
+ continue;
+
+ if (is_subselect) // is subselect
{
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
table_list->table->file->delete_all_rows();
@@ -4562,6 +4572,7 @@ bool get_schema_tables_result(JOIN *join)
if (table_list->schema_table->fill_table(thd, table_list,
tab->select_cond))
result= 1;
+ table_list->is_schema_table_processed= TRUE;
}
}
thd->no_warnings_for_error= 0;
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index c4448ff8abe..bf86630d28c 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -450,7 +450,7 @@ void mysql_print_status()
calc_sum_of_all_status(&tmp);
printf("\nStatus information:\n\n");
- my_getwd(current_dir, sizeof(current_dir),MYF(0));
+ VOID(my_getwd(current_dir, sizeof(current_dir),MYF(0)));
printf("Current dir: %s\n", current_dir);
printf("Running threads: %d Stack size: %ld\n", thread_count,
(long) thread_stack);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a116dc27891..f83d7b28d6f 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1642,11 +1642,26 @@ clear_privileges:
sp_name:
ident '.' ident
{
+ if (!$1.str || check_db_name($1.str))
+ {
+ my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
+ YYABORT;
+ }
+ if (check_routine_name($3))
+ {
+ my_error(ER_SP_WRONG_NAME, MYF(0), $3.str);
+ YYABORT;
+ }
$$= new sp_name($1, $3);
$$->init_qname(YYTHD);
}
| ident
{
+ if (check_routine_name($1))
+ {
+ my_error(ER_SP_WRONG_NAME, MYF(0), $1.str);
+ YYABORT;
+ }
$$= sp_name_current_db_new(YYTHD, $1);
}
;
diff --git a/sql/table.cc b/sql/table.cc
index b912683d371..b7920d0d530 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1640,7 +1640,10 @@ ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
ret_value=uint4korr(pos);
}
if (! save_names)
- my_free((gptr) buf,MYF(0));
+ {
+ if (names)
+ my_free((gptr) buf,MYF(0));
+ }
else if (!names)
bzero((char*) save_names,sizeof(save_names));
else
diff --git a/sql/table.h b/sql/table.h
index bcc2f89655b..a799d4389fb 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -560,6 +560,7 @@ typedef struct st_table_list
st_select_lex_unit *derived; /* SELECT_LEX_UNIT of derived table */
ST_SCHEMA_TABLE *schema_table; /* Information_schema table */
st_select_lex *schema_select_lex;
+ bool is_schema_table_processed;
/*
True when the view field translation table is used to convert
schema table fields for backwards compatibility with SHOW command.
diff --git a/sql/uniques.cc b/sql/uniques.cc
index 367aed2d113..ad074f8b2b0 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -38,8 +38,8 @@
int unique_write_to_file(gptr key, element_count count, Unique *unique)
{
/*
- Use unique->size (size of element stored in the tree) and not
- unique->tree.size_of_element. The latter is different from unique->size
+ Use unique->size (size of element stored in the tree) and not
+ unique->tree.size_of_element. The latter is different from unique->size
when tree implementation chooses to store pointer to key in TREE_ELEMENT
(instead of storing the element itself there)
*/
@@ -63,27 +63,27 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
comp_func_fixed_arg);
/* If the following fail's the next add will also fail */
my_init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16);
- /*
+ /*
If you change the following, change it in get_max_elements function, too.
*/
max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size);
- open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
- MYF(MY_WME));
+ VOID(open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
+ MYF(MY_WME)));
}
/*
Calculate log2(n!)
-
+
NOTES
Stirling's approximate formula is used:
-
- n! ~= sqrt(2*M_PI*n) * (n/M_E)^n
-
+
+ n! ~= sqrt(2*M_PI*n) * (n/M_E)^n
+
Derivation of formula used for calculations is as follows:
log2(n!) = log(n!)/log(2) = log(sqrt(2*M_PI*n)*(n/M_E)^n) / log(2) =
-
+
= (log(2*M_PI*n)/2 + n*log(n/M_E)) / log(2).
*/
@@ -94,7 +94,7 @@ inline double log2_n_fact(double x)
/*
- Calculate cost of merge_buffers function call for given sequence of
+ Calculate cost of merge_buffers function call for given sequence of
input stream lengths and store the number of rows in result stream in *last.
SYNOPSIS
@@ -103,21 +103,21 @@ inline double log2_n_fact(double x)
elem_size Size of element stored in buffer
first Pointer to first merged element size
last Pointer to last merged element size
-
+
RETURN
Cost of merge_buffers operation in disk seeks.
-
+
NOTES
It is assumed that no rows are eliminated during merge.
- The cost is calculated as
-
+ The cost is calculated as
+
cost(read_and_write) + cost(merge_comparisons).
-
- All bytes in the sequences is read and written back during merge so cost
+
+ All bytes in the sequences is read and written back during merge so cost
of disk io is 2*elem_size*total_buf_elems/IO_SIZE (2 is for read + write)
-
+
For comparisons cost calculations we assume that all merged sequences have
- the same length, so each of total_buf_size elements will be added to a sort
+ the same length, so each of total_buf_size elements will be added to a sort
heap with (n_buffers-1) elements. This gives the comparison cost:
total_buf_elems* log2(n_buffers) / TIME_FOR_COMPARE_ROWID;
@@ -125,16 +125,16 @@ inline double log2_n_fact(double x)
static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
uint *first, uint *last)
-{
+{
uint total_buf_elems= 0;
for (uint *pbuf= first; pbuf <= last; pbuf++)
total_buf_elems+= *pbuf;
*last= total_buf_elems;
-
+
int n_buffers= last - first + 1;
/* Using log2(n)=log(n)/log(2) formula */
- return 2*((double)total_buf_elems*elem_size) / IO_SIZE +
+ return 2*((double)total_buf_elems*elem_size) / IO_SIZE +
total_buf_elems*log((double) n_buffers) / (TIME_FOR_COMPARE_ROWID * M_LN2);
}
@@ -142,13 +142,13 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
/*
Calculate cost of merging buffers into one in Unique::get, i.e. calculate
how long (in terms of disk seeks) the two calls
- merge_many_buffs(...);
- merge_buffers(...);
+ merge_many_buffs(...);
+ merge_buffers(...);
will take.
SYNOPSIS
get_merge_many_buffs_cost()
- buffer buffer space for temporary data, at least
+ buffer buffer space for temporary data, at least
Unique::get_cost_calc_buff_size bytes
maxbuffer # of full buffers
max_n_elems # of elements in first maxbuffer buffers
@@ -156,12 +156,12 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
elem_size size of buffer element
NOTES
- maxbuffer+1 buffers are merged, where first maxbuffer buffers contain
+ maxbuffer+1 buffers are merged, where first maxbuffer buffers contain
max_n_elems elements each and last buffer contains last_n_elems elements.
The current implementation does a dumb simulation of merge_many_buffs
function actions.
-
+
RETURN
Cost of merge in disk seeks.
*/
@@ -173,17 +173,17 @@ static double get_merge_many_buffs_cost(uint *buffer,
register int i;
double total_cost= 0.0;
uint *buff_elems= buffer; /* #s of elements in each of merged sequences */
-
- /*
+
+ /*
Set initial state: first maxbuffer sequences contain max_n_elems elements
each, last sequence contains last_n_elems elements.
*/
for (i = 0; i < (int)maxbuffer; i++)
- buff_elems[i]= max_n_elems;
+ buff_elems[i]= max_n_elems;
buff_elems[maxbuffer]= last_n_elems;
- /*
- Do it exactly as merge_many_buff function does, calling
+ /*
+ Do it exactly as merge_many_buff function does, calling
get_merge_buffers_cost to get cost of merge_buffers.
*/
if (maxbuffer >= MERGEBUFF2)
@@ -194,17 +194,17 @@ static double get_merge_many_buffs_cost(uint *buffer,
for (i = 0; i <= (int) maxbuffer - MERGEBUFF*3/2; i += MERGEBUFF)
{
total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
- buff_elems + i,
+ buff_elems + i,
buff_elems + i + MERGEBUFF-1);
lastbuff++;
}
total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
- buff_elems + i,
+ buff_elems + i,
buff_elems + maxbuffer);
maxbuffer= lastbuff;
}
}
-
+
/* Simulate final merge_buff call. */
total_cost += get_merge_buffers_cost(buff_elems, elem_size,
buff_elems, buff_elems + maxbuffer);
@@ -213,7 +213,7 @@ static double get_merge_many_buffs_cost(uint *buffer,
/*
- Calculate cost of using Unique for processing nkeys elements of size
+ Calculate cost of using Unique for processing nkeys elements of size
key_size using max_in_memory_size memory.
SYNOPSIS
@@ -223,12 +223,12 @@ static double get_merge_many_buffs_cost(uint *buffer,
nkeys #of elements in Unique
key_size size of each elements in bytes
max_in_memory_size amount of memory Unique will be allowed to use
-
+
RETURN
Cost in disk seeks.
-
+
NOTES
- cost(using_unqiue) =
+ cost(using_unqiue) =
cost(create_trees) + (see #1)
cost(merge) + (see #2)
cost(read_result) (see #3)
@@ -237,42 +237,42 @@ static double get_merge_many_buffs_cost(uint *buffer,
For each Unique::put operation there will be 2*log2(n+1) elements
comparisons, where n runs from 1 tree_size (we assume that all added
elements are different). Together this gives:
-
+
n_compares = 2*(log2(2) + log2(3) + ... + log2(N+1)) = 2*log2((N+1)!)
-
+
then cost(tree_creation) = n_compares*ROWID_COMPARE_COST;
Total cost of creating trees:
(n_trees - 1)*max_size_tree_cost + non_max_size_tree_cost.
Approximate value of log2(N!) is calculated by log2_n_fact function.
-
+
2. Cost of merging.
If only one tree is created by Unique no merging will be necessary.
Otherwise, we model execution of merge_many_buff function and count
- #of merges. (The reason behind this is that number of buffers is small,
- while size of buffers is big and we don't want to loose precision with
+ #of merges. (The reason behind this is that number of buffers is small,
+ while size of buffers is big and we don't want to loose precision with
O(x)-style formula)
-
+
3. If only one tree is created by Unique no disk io will happen.
- Otherwise, ceil(key_len*n_keys) disk seeks are necessary. We assume
+ Otherwise, ceil(key_len*n_keys) disk seeks are necessary. We assume
these will be random seeks.
*/
-double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
+double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
ulong max_in_memory_size)
{
ulong max_elements_in_tree;
ulong last_tree_elems;
int n_full_trees; /* number of trees in unique - 1 */
double result;
-
- max_elements_in_tree=
+
+ max_elements_in_tree=
max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size);
n_full_trees= nkeys / max_elements_in_tree;
last_tree_elems= nkeys % max_elements_in_tree;
-
+
/* Calculate cost of creating trees */
result= 2*log2_n_fact(last_tree_elems + 1.0);
if (n_full_trees)
@@ -285,13 +285,13 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
if (!n_full_trees)
return result;
-
- /*
+
+ /*
There is more then one tree and merging is necessary.
First, add cost of writing all trees to disk, assuming that all disk
writes are sequential.
*/
- result += DISK_SEEK_BASE_COST * n_full_trees *
+ result += DISK_SEEK_BASE_COST * n_full_trees *
ceil(((double) key_size)*max_elements_in_tree / IO_SIZE);
result += DISK_SEEK_BASE_COST * ceil(((double) key_size)*last_tree_elems / IO_SIZE);
@@ -303,8 +303,8 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
return merge_cost;
result += merge_cost;
- /*
- Add cost of reading the resulting sequence, assuming there were no
+ /*
+ Add cost of reading the resulting sequence, assuming there were no
duplicate elements.
*/
result += ceil((double)key_size*nkeys/IO_SIZE);
@@ -320,7 +320,7 @@ Unique::~Unique()
}
- /* Write tree to disk; clear tree */
+ /* Write tree to disk; clear tree */
bool Unique::flush()
{
BUFFPEK file_ptr;
@@ -359,7 +359,7 @@ Unique::reset()
}
elements= 0;
}
-
+
/*
The comparison function, passed to queue_init() in merge_walk() must
use comparison function of Uniques::tree, but compare members of struct
@@ -386,7 +386,7 @@ C_MODE_END
/*
DESCRIPTION
- Function is very similar to merge_buffers, but instead of writing sorted
+ Function is very similar to merge_buffers, but instead of writing sorted
unique keys to the output file, it invokes walk_action for each key.
This saves I/O if you need to pass through all unique keys only once.
SYNOPSIS
@@ -601,7 +601,7 @@ bool Unique::get(TABLE *table)
bool error=1;
/* Open cached file if it isn't open */
- outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
+ outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
MYF(MY_ZEROFILL));
if (!outfile || ! my_b_inited(outfile) &&
@@ -618,7 +618,7 @@ bool Unique::get(TABLE *table)
sort_param.keys= max_in_memory_size / sort_param.sort_length;
sort_param.not_killable=1;
- if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) *
+ if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) *
sort_param.sort_length,
MYF(0))))
return 1;
@@ -633,7 +633,7 @@ bool Unique::get(TABLE *table)
goto err;
if (merge_buffers(&sort_param, &file, outfile, sort_buffer, file_ptr,
file_ptr, file_ptr+maxbuffer,0))
- goto err;
+ goto err;
error=0;
err:
x_free((gptr) sort_buffer);
diff --git a/storage/myisam/ft_update.c b/storage/myisam/ft_update.c
index a280a98cf90..1ec91b41218 100644
--- a/storage/myisam/ft_update.c
+++ b/storage/myisam/ft_update.c
@@ -174,6 +174,10 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
FT_SEG_ITERATOR ftsi1, ftsi2;
CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset;
DBUG_ENTER("_mi_ft_cmp");
+#ifndef MYSQL_HAS_TRUE_CTYPE_IMPLEMENTATION
+ if (cs->mbmaxlen > 1)
+ DBUG_RETURN(THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT);
+#endif
_mi_ft_segiterator_init(info, keynr, rec1, &ftsi1);
_mi_ft_segiterator_init(info, keynr, rec2, &ftsi2);
diff --git a/storage/myisam/mi_delete.c b/storage/myisam/mi_delete.c
index 416d951d138..2010b684300 100644
--- a/storage/myisam/mi_delete.c
+++ b/storage/myisam/mi_delete.c
@@ -276,7 +276,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (subkeys == -1)
{
/* the last entry in sub-tree */
- _mi_dispose(info, keyinfo, root,DFLT_INIT_HITS);
+ if (_mi_dispose(info, keyinfo, root,DFLT_INIT_HITS))
+ DBUG_RETURN(-1);
/* fall through to normal delete */
}
else
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index d691c24e890..e80a3ffacd9 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -1159,7 +1159,7 @@ static int compare_huff_elements(void *not_used __attribute__((unused)),
static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
my_off_t records)
{
- uint space_fields,fill_zero_fields,field_count[(int) FIELD_VARCHAR+1];
+ uint space_fields,fill_zero_fields,field_count[(int) FIELD_enum_val_count];
my_off_t old_length,new_length,length;
DBUG_ENTER("check_counts");
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index c3eaddb3e92..c9562461f56 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -376,7 +376,10 @@ pthread_handler_t thr_find_all_keys(void *arg)
{
if (my_init_dynamic_array(&info->buffpek, sizeof(BUFFPEK),
maxbuffer, maxbuffer/2))
+ {
my_free((gptr) sort_keys,MYF(0));
+ sort_keys= (uchar **) NULL; /* for err: label */
+ }
else
break;
}
diff --git a/storage/ndb/include/logger/LogHandler.hpp b/storage/ndb/include/logger/LogHandler.hpp
index 7df6ad864e5..8b9aa43d7a9 100644
--- a/storage/ndb/include/logger/LogHandler.hpp
+++ b/storage/ndb/include/logger/LogHandler.hpp
@@ -126,6 +126,18 @@ public:
void setErrorCode(int code);
/**
+ * Returns the error string.
+ */
+ char* getErrorStr();
+
+ /**
+ * Sets the error string.
+ *
+ * @param str the error string.
+ */
+ void setErrorStr(char* str);
+
+ /**
* Parse logstring parameters
*
* @param params list of parameters, formatted as "param=value",
@@ -195,6 +207,7 @@ private:
const char* m_pDateTimeFormat;
int m_errorCode;
+ char* m_errorStr;
// for handling repeated messages
unsigned m_count_repeated_messages;
diff --git a/storage/ndb/include/logger/Logger.hpp b/storage/ndb/include/logger/Logger.hpp
index ee762098fb6..3414468d42d 100644
--- a/storage/ndb/include/logger/Logger.hpp
+++ b/storage/ndb/include/logger/Logger.hpp
@@ -178,8 +178,11 @@ public:
* Add a new handler
*
* @param logstring string describing the handler to add
+ * @param err OS errno in event of error
+ * @param len max length of errStr buffer
+ * @param errStr logger error string in event of error
*/
- bool addHandler(const BaseString &logstring);
+ bool addHandler(const BaseString &logstring, int *err, int len, char* errStr);
/**
* Remove a log handler.
diff --git a/storage/ndb/include/mgmapi/mgmapi.h b/storage/ndb/include/mgmapi/mgmapi.h
index 2675502b6ad..9d74be5d603 100644
--- a/storage/ndb/include/mgmapi/mgmapi.h
+++ b/storage/ndb/include/mgmapi/mgmapi.h
@@ -992,6 +992,22 @@ extern "C" {
int ndb_mgm_alloc_nodeid(NdbMgmHandle handle,
unsigned version, int nodetype);
+ /**
+ * End Session
+ *
+ * This function tells the mgm server to free all resources associated with
+ * this connection. It will also close it.
+ *
+ * This differs from just disconnecting as we now synchronously clean up,
+ * so that a quickly restarting server that needs the same node id can
+ * get it when it restarts.
+ *
+ * @param handle NDB management handle
+ * @return 0 on success
+ *
+ * @note you still have to destroy the NdbMgmHandle.
+ */
+ int ndb_mgm_end_session(NdbMgmHandle handle);
/**
* Get the node id of the mgm server we're connected to
diff --git a/storage/ndb/include/mgmcommon/ConfigRetriever.hpp b/storage/ndb/include/mgmcommon/ConfigRetriever.hpp
index c0b877af07d..1b4ecd56f80 100644
--- a/storage/ndb/include/mgmcommon/ConfigRetriever.hpp
+++ b/storage/ndb/include/mgmcommon/ConfigRetriever.hpp
@@ -78,6 +78,7 @@ public:
const char *get_connectstring(char *buf, int buf_sz) const;
NdbMgmHandle get_mgmHandle() { return m_handle; };
NdbMgmHandle* get_mgmHandlePtr() { return &m_handle; };
+ void end_session(bool end) { m_end_session= end; };
Uint32 get_configuration_nodeid() const;
private:
@@ -92,6 +93,8 @@ private:
void setError(ErrorType, const char * errorMsg);
Uint32 _ownNodeId;
+ bool m_end_session;
+
/*
Uint32 m_mgmd_port;
const char *m_mgmd_host;
diff --git a/storage/ndb/src/common/logger/FileLogHandler.cpp b/storage/ndb/src/common/logger/FileLogHandler.cpp
index 8678b999b6f..3d29e63ac1f 100644
--- a/storage/ndb/src/common/logger/FileLogHandler.cpp
+++ b/storage/ndb/src/common/logger/FileLogHandler.cpp
@@ -187,6 +187,7 @@ FileLogHandler::setParam(const BaseString &param, const BaseString &value){
return setMaxSize(value);
if(param == "maxfiles")
return setMaxFiles(value);
+ setErrorStr("Invalid parameter");
return false;
}
@@ -196,16 +197,18 @@ FileLogHandler::setFilename(const BaseString &filename) {
if(m_pLogFile)
delete m_pLogFile;
m_pLogFile = new File_class(filename.c_str(), "a+");
- open();
- return true;
+ return open();
}
bool
FileLogHandler::setMaxSize(const BaseString &size) {
char *end;
long val = strtol(size.c_str(), &end, 0); /* XXX */
- if(size.c_str() == end)
+ if(size.c_str() == end || val < 0)
+ {
+ setErrorStr("Invalid file size");
return false;
+ }
if(end[0] == 'M')
val *= 1024*1024;
if(end[0] == 'k')
@@ -220,8 +223,11 @@ bool
FileLogHandler::setMaxFiles(const BaseString &files) {
char *end;
long val = strtol(files.c_str(), &end, 0);
- if(files.c_str() == end)
+ if(files.c_str() == end || val < 1)
+ {
+ setErrorStr("Invalid maximum number of files");
return false;
+ }
m_maxNoFiles = val;
return true;
@@ -230,6 +236,9 @@ FileLogHandler::setMaxFiles(const BaseString &files) {
bool
FileLogHandler::checkParams() {
if(m_pLogFile == NULL)
+ {
+ setErrorStr("Log file cannot be null.");
return false;
+ }
return true;
}
diff --git a/storage/ndb/src/common/logger/LogHandler.cpp b/storage/ndb/src/common/logger/LogHandler.cpp
index 521bd346fd3..c11f962d4fb 100644
--- a/storage/ndb/src/common/logger/LogHandler.cpp
+++ b/storage/ndb/src/common/logger/LogHandler.cpp
@@ -23,7 +23,8 @@
//
LogHandler::LogHandler() :
m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"),
- m_errorCode(0)
+ m_errorCode(0),
+ m_errorStr(NULL)
{
m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds
m_count_repeated_messages= 0;
@@ -155,6 +156,19 @@ LogHandler::setErrorCode(int code)
m_errorCode = code;
}
+
+char*
+LogHandler::getErrorStr()
+{
+ return m_errorStr;
+}
+
+void
+LogHandler::setErrorStr(char* str)
+{
+ m_errorStr= str;
+}
+
bool
LogHandler::parseParams(const BaseString &_params) {
Vector<BaseString> v_args;
@@ -165,9 +179,18 @@ LogHandler::parseParams(const BaseString &_params) {
for(size_t i=0; i < v_args.size(); i++) {
Vector<BaseString> v_param_value;
if(v_args[i].split(v_param_value, "=", 2) != 2)
+ {
ret = false;
- else if (!setParam(v_param_value[0], v_param_value[1]))
- ret = false;
+ setErrorStr("Can't find key=value pair.");
+ }
+ else
+ {
+ v_param_value[0].trim(" \t");
+ if (!setParam(v_param_value[0], v_param_value[1]))
+ {
+ ret = false;
+ }
+ }
}
if(!checkParams())
diff --git a/storage/ndb/src/common/logger/Logger.cpp b/storage/ndb/src/common/logger/Logger.cpp
index 4a48236053d..48e084a782b 100644
--- a/storage/ndb/src/common/logger/Logger.cpp
+++ b/storage/ndb/src/common/logger/Logger.cpp
@@ -167,7 +167,7 @@ Logger::addHandler(LogHandler* pHandler)
}
bool
-Logger::addHandler(const BaseString &logstring) {
+Logger::addHandler(const BaseString &logstring, int *err, int len, char* errStr) {
size_t i;
Vector<BaseString> logdest;
Vector<LogHandler *>loghandlers;
@@ -200,9 +200,18 @@ Logger::addHandler(const BaseString &logstring) {
handler = new ConsoleLogHandler();
if(handler == NULL)
+ {
+ snprintf(errStr,len,"Could not create log destination: %s",
+ logdest[i].c_str());
DBUG_RETURN(false);
+ }
if(!handler->parseParams(params))
+ {
+ *err= handler->getErrorCode();
+ if(handler->getErrorStr())
+ strncpy(errStr, handler->getErrorStr(), len);
DBUG_RETURN(false);
+ }
loghandlers.push_back(handler);
}
diff --git a/storage/ndb/src/common/logger/SysLogHandler.cpp b/storage/ndb/src/common/logger/SysLogHandler.cpp
index 5b1b8d85ca7..c7fcb102dd4 100644
--- a/storage/ndb/src/common/logger/SysLogHandler.cpp
+++ b/storage/ndb/src/common/logger/SysLogHandler.cpp
@@ -154,5 +154,6 @@ SysLogHandler::setFacility(const BaseString &facility) {
return true;
}
}
+ setErrorStr("Invalid syslog facility name");
return false;
}
diff --git a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
index 3b843b6708b..97de5c7f83d 100644
--- a/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
+++ b/storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp
@@ -52,6 +52,7 @@ ConfigRetriever::ConfigRetriever(const char * _connect_string,
m_version = version;
m_node_type = node_type;
_ownNodeId= 0;
+ m_end_session= true;
m_handle= ndb_mgm_create_handle();
@@ -76,6 +77,8 @@ ConfigRetriever::~ConfigRetriever()
{
DBUG_ENTER("ConfigRetriever::~ConfigRetriever");
if (m_handle) {
+ if(m_end_session)
+ ndb_mgm_end_session(m_handle);
ndb_mgm_disconnect(m_handle);
ndb_mgm_destroy_handle(&m_handle);
}
diff --git a/storage/ndb/src/common/util/SocketServer.cpp b/storage/ndb/src/common/util/SocketServer.cpp
index 15dca2d96b1..481c656b78b 100644
--- a/storage/ndb/src/common/util/SocketServer.cpp
+++ b/storage/ndb/src/common/util/SocketServer.cpp
@@ -42,6 +42,8 @@ SocketServer::~SocketServer() {
delete m_sessions[i].m_session;
}
for(i = 0; i<m_services.size(); i++){
+ if(m_services[i].m_socket)
+ NDB_CLOSE_SOCKET(m_services[i].m_socket);
delete m_services[i].m_service;
}
}
diff --git a/storage/ndb/src/kernel/main.cpp b/storage/ndb/src/kernel/main.cpp
index 2374cce5f35..4bc9fbf76e5 100644
--- a/storage/ndb/src/kernel/main.cpp
+++ b/storage/ndb/src/kernel/main.cpp
@@ -307,8 +307,11 @@ int main(int argc, char** argv)
/**
* We no longer need the mgm connection in this process
* (as we are the angel, not ndb)
+ *
+ * We don't want to purge any allocated resources (nodeid), so
+ * we set that option to false
*/
- theConfig->closeConfiguration();
+ theConfig->closeConfiguration(false);
int status = 0, error_exit = 0, signum = 0;
while(waitpid(child, &status, 0) != child);
diff --git a/storage/ndb/src/kernel/vm/Configuration.cpp b/storage/ndb/src/kernel/vm/Configuration.cpp
index fe7d474b578..771fa6f5fe4 100644
--- a/storage/ndb/src/kernel/vm/Configuration.cpp
+++ b/storage/ndb/src/kernel/vm/Configuration.cpp
@@ -172,7 +172,8 @@ Configuration::~Configuration(){
}
void
-Configuration::closeConfiguration(){
+Configuration::closeConfiguration(bool end_session){
+ m_config_retriever->end_session(end_session);
if (m_config_retriever) {
delete m_config_retriever;
}
diff --git a/storage/ndb/src/kernel/vm/Configuration.hpp b/storage/ndb/src/kernel/vm/Configuration.hpp
index 5043d1f0bee..243ecbee4e7 100644
--- a/storage/ndb/src/kernel/vm/Configuration.hpp
+++ b/storage/ndb/src/kernel/vm/Configuration.hpp
@@ -35,7 +35,7 @@ public:
void fetch_configuration();
void setupConfiguration();
- void closeConfiguration();
+ void closeConfiguration(bool end_session= true);
bool lockPagesInMainMemory() const;
diff --git a/storage/ndb/src/mgmapi/mgmapi.cpp b/storage/ndb/src/mgmapi/mgmapi.cpp
index 79284964186..eb93ec88b6f 100644
--- a/storage/ndb/src/mgmapi/mgmapi.cpp
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp
@@ -2321,4 +2321,23 @@ int ndb_mgm_report_event(NdbMgmHandle handle, Uint32 *data, Uint32 length)
DBUG_RETURN(0);
}
+extern "C"
+int ndb_mgm_end_session(NdbMgmHandle handle)
+{
+ DBUG_ENTER("ndb_mgm_end_session");
+ CHECK_HANDLE(handle, 0);
+ CHECK_CONNECTED(handle, 0);
+
+ SocketOutputStream s_output(handle->socket);
+ s_output.println("end session");
+ s_output.println("");
+
+ SocketInputStream in(handle->socket, handle->read_timeout);
+ char buf[32];
+
+ in.gets(buf, sizeof(buf));
+
+ DBUG_RETURN(0);
+}
+
template class Vector<const ParserRow<ParserDummy>*>;
diff --git a/storage/ndb/src/mgmclient/CommandInterpreter.cpp b/storage/ndb/src/mgmclient/CommandInterpreter.cpp
index b398ed46514..5496b2dadc3 100644
--- a/storage/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/storage/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -928,26 +928,21 @@ CommandInterpreter::executeShutdown(char* parameters)
int result = 0;
result = ndb_mgm_stop(m_mgmsrv, 0, 0);
if (result < 0) {
- ndbout << "Shutdown off NDB Cluster storage node(s) failed." << endl;
+ ndbout << "Shutdown of NDB Cluster node(s) failed." << endl;
printError();
return result;
}
- ndbout << result << " NDB Cluster storage node(s) have shutdown." << endl;
+ ndbout << result << " NDB Cluster node(s) have shutdown." << endl;
int mgm_id= 0;
- for(int i=0; i < state->no_of_nodes; i++) {
- if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_MGM &&
- state->node_states[i].version != 0){
- if (mgm_id == 0)
- mgm_id= state->node_states[i].node_id;
- else {
- ndbout << "Unable to locate management server, "
- << "shutdown manually with <id> STOP"
- << endl;
- return 1;
- }
- }
+ mgm_id= ndb_mgm_get_mgmd_nodeid(m_mgmsrv);
+ if (mgm_id == 0)
+ {
+ ndbout << "Unable to locate management server, "
+ << "shutdown manually with <id> STOP"
+ << endl;
+ return 1;
}
result = ndb_mgm_stop(m_mgmsrv, 1, &mgm_id);
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
index cf9965b94e0..b60679f700e 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -60,6 +60,9 @@
#include <SignalSender.hpp>
+extern bool g_StopServer;
+extern bool g_RestartServer;
+
//#define MGM_SRV_DEBUG
#ifdef MGM_SRV_DEBUG
#define DEBUG(x) do ndbout << x << endl; while(0)
@@ -179,6 +182,8 @@ MgmtSrvr::startEventLog()
}
const char * tmp;
+ char errStr[100];
+ int err= 0;
BaseString logdest;
char *clusterLog= NdbConfig_ClusterLogFileName(_ownNodeId);
NdbAutoPtr<char> tmp_aptr(clusterLog);
@@ -192,9 +197,17 @@ MgmtSrvr::startEventLog()
logdest.assfmt("FILE:filename=%s,maxsize=1000000,maxfiles=6",
clusterLog);
}
- if(!g_eventLogger.addHandler(logdest)) {
+ errStr[0]='\0';
+ if(!g_eventLogger.addHandler(logdest, &err, sizeof(errStr), errStr)) {
ndbout << "Warning: could not add log destination \""
- << logdest.c_str() << "\"" << endl;
+ << logdest.c_str() << "\". Reason: ";
+ if(err)
+ ndbout << strerror(err);
+ if(err && errStr[0]!='\0')
+ ndbout << ", ";
+ if(errStr[0]!='\0')
+ ndbout << errStr;
+ ndbout << endl;
}
}
@@ -373,7 +386,8 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
_ownReference(0),
theSignalIdleList(NULL),
theWaitState(WAIT_SUBSCRIBE_CONF),
- m_event_listner(this)
+ m_event_listner(this),
+ m_local_mgm_handle(0)
{
DBUG_ENTER("MgmtSrvr::MgmtSrvr");
@@ -537,6 +551,8 @@ MgmtSrvr::check_start()
bool
MgmtSrvr::start(BaseString &error_string)
{
+ int mgm_connect_result;
+
DBUG_ENTER("MgmtSrvr::start");
if (_props == NULL) {
if (!check_start()) {
@@ -574,6 +590,13 @@ MgmtSrvr::start(BaseString &error_string)
DBUG_RETURN(false);
}
+ if((mgm_connect_result= connect_to_self()) < 0)
+ {
+ ndbout_c("Unable to connect to our own ndb_mgmd (Error %d)",
+ mgm_connect_result);
+ ndbout_c("This is probably a bug.");
+ }
+
TransporterRegistry *reg = theFacade->get_registry();
for(unsigned int i=0;i<reg->m_transporter_interface.size();i++) {
BaseString msg;
@@ -831,9 +854,81 @@ MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address)
return 0;
}
+int MgmtSrvr::sendStopMgmd(NodeId nodeId,
+ bool abort,
+ bool stop,
+ bool restart,
+ bool nostart,
+ bool initialStart)
+{
+ const char* hostname;
+ Uint32 port;
+ BaseString connect_string;
+
+ {
+ Guard g(m_configMutex);
+ {
+ ndb_mgm_configuration_iterator
+ iter(* _config->m_configValues, CFG_SECTION_NODE);
+
+ if(iter.first()) return SEND_OR_RECEIVE_FAILED;
+ if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED;
+ if(iter.get(CFG_NODE_HOST, &hostname)) return SEND_OR_RECEIVE_FAILED;
+ }
+ {
+ ndb_mgm_configuration_iterator
+ iter(* _config->m_configValues, CFG_SECTION_NODE);
+
+ if(iter.first()) return SEND_OR_RECEIVE_FAILED;
+ if(iter.find(CFG_NODE_ID, nodeId)) return SEND_OR_RECEIVE_FAILED;
+ if(iter.get(CFG_MGM_PORT, &port)) return SEND_OR_RECEIVE_FAILED;
+ }
+ if( strlen(hostname) == 0 )
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ connect_string.assfmt("%s:%u",hostname,port);
+
+ DBUG_PRINT("info",("connect string: %s",connect_string.c_str()));
+
+ NdbMgmHandle h= ndb_mgm_create_handle();
+ if ( h && connect_string.length() > 0 )
+ {
+ ndb_mgm_set_connectstring(h,connect_string.c_str());
+ if(ndb_mgm_connect(h,1,0,0))
+ {
+ DBUG_PRINT("info",("failed ndb_mgm_connect"));
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ if(!restart)
+ {
+ if(ndb_mgm_stop(h, 1, (const int*)&nodeId) < 0)
+ {
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ }
+ else
+ {
+ int nodes[1];
+ nodes[0]= (int)nodeId;
+ if(ndb_mgm_restart2(h, 1, nodes, initialStart, nostart, abort) < 0)
+ {
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ }
+ }
+ ndb_mgm_destroy_handle(&h);
+
+ return 0;
+}
+
/*
* Common method for handeling all STOP_REQ signalling that
* is used by Stopping, Restarting and Single user commands
+ *
+ * In the event that we need to stop a mgmd, we create a mgm
+ * client connection to that mgmd and stop it that way.
+ * This allows us to stop mgm servers when there isn't any real
+ * distributed communication up.
*/
int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
@@ -845,6 +940,8 @@ int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
bool nostart,
bool initialStart)
{
+ int error = 0;
+
stoppedNodes.clear();
SignalSender ss(theFacade);
@@ -883,18 +980,34 @@ int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
NodeBitmask nodes;
if (nodeId)
{
+ if(nodeId==getOwnNodeId())
{
- int r;
- if((r = okToSendTo(nodeId, true)) != 0)
- return r;
+ if(restart)
+ g_RestartServer= true;
+ g_StopServer= true;
+ return 0;
}
+ if(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
{
+ int r;
+ if((r= okToSendTo(nodeId, true)) != 0)
+ return r;
if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
return SEND_OR_RECEIVE_FAILED;
}
+ else if(getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
+ {
+ error= sendStopMgmd(nodeId, abort, stop, restart, nostart, initialStart);
+ if(error==0)
+ stoppedNodes.set(nodeId);
+ return error;
+ }
+ else
+ return WRONG_PROCESS_TYPE;
nodes.set(nodeId);
}
else
+ {
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
{
if(okToSendTo(nodeId, true) == 0)
@@ -904,9 +1017,17 @@ int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
nodes.set(nodeId);
}
}
+ nodeId= 0;
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM))
+ {
+ if(nodeId==getOwnNodeId())
+ continue;
+ if(sendStopMgmd(nodeId, abort, stop, restart, nostart, initialStart)==0)
+ stoppedNodes.set(nodeId);
+ }
+ }
// now wait for the replies
- int error = 0;
while (!nodes.isclear())
{
SimpleSignal *signal = ss.waitFor();
@@ -2552,9 +2673,23 @@ void MgmtSrvr::transporter_connect(NDB_SOCKET_TYPE sockfd)
}
}
-int MgmtSrvr::set_connect_string(const char *str)
+int MgmtSrvr::connect_to_self(void)
{
- return ndb_mgm_set_connectstring(m_config_retriever->get_mgmHandle(),str);
+ int r= 0;
+ m_local_mgm_handle= ndb_mgm_create_handle();
+ snprintf(m_local_mgm_connect_string,sizeof(m_local_mgm_connect_string),
+ "localhost:%u",getPort());
+ ndb_mgm_set_connectstring(m_local_mgm_handle, m_local_mgm_connect_string);
+
+ if((r= ndb_mgm_connect(m_local_mgm_handle, 0, 0, 0)) < 0)
+ {
+ ndb_mgm_destroy_handle(&m_local_mgm_handle);
+ return r;
+ }
+ // TransporterRegistry now owns this NdbMgmHandle and will destroy it.
+ theFacade->get_registry()->set_mgm_handle(m_local_mgm_handle);
+
+ return 0;
}
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
index ec6ab47bc2a..20e6ff1bc43 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -466,7 +466,7 @@ public:
int getConnectionDbParameter(int node1, int node2, int param,
int *value, BaseString& msg);
- int set_connect_string(const char *str);
+ int connect_to_self(void);
void transporter_connect(NDB_SOCKET_TYPE sockfd);
@@ -482,6 +482,13 @@ private:
int send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type);
+ int sendStopMgmd(NodeId nodeId,
+ bool abort,
+ bool stop,
+ bool restart,
+ bool nostart,
+ bool initialStart);
+
int sendSTOP_REQ(NodeId nodeId,
NodeBitmask &stoppedNodes,
Uint32 singleUserNodeId,
@@ -625,6 +632,8 @@ private:
// signal arrives.
// We wait in receiveOptimisedResponse and signal in handleReceivedSignal.
+ NdbMgmHandle m_local_mgm_handle;
+ char m_local_mgm_connect_string[20];
class TransporterFacade * theFacade;
int sendVersionReq( int processId, Uint32 &version, const char **address);
diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp
index ee24cf18941..80f0aa2eda8 100644
--- a/storage/ndb/src/mgmsrv/Services.cpp
+++ b/storage/ndb/src/mgmsrv/Services.cpp
@@ -203,6 +203,8 @@ ParserRow<MgmApiSession> commands[] = {
MGM_CMD("bye", &MgmApiSession::bye, ""),
+ MGM_CMD("end session", &MgmApiSession::endSession, ""),
+
MGM_CMD("set loglevel", &MgmApiSession::setLogLevel, ""),
MGM_ARG("node", Int, Mandatory, "Node"),
MGM_ARG("category", Int, Mandatory, "Event category"),
@@ -719,11 +721,22 @@ MgmApiSession::dumpState(Parser<MgmApiSession>::Context &,
void
MgmApiSession::bye(Parser<MgmApiSession>::Context &,
- Properties const &) {
+ Properties const &) {
m_stop = true;
}
void
+MgmApiSession::endSession(Parser<MgmApiSession>::Context &,
+ Properties const &) {
+ if(m_allocated_resources)
+ delete m_allocated_resources;
+
+ m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
+
+ m_output->println("end session reply");
+}
+
+void
MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
Properties const &args) {
const char *reply= "set cluster loglevel reply";
diff --git a/storage/ndb/src/mgmsrv/Services.hpp b/storage/ndb/src/mgmsrv/Services.hpp
index 30f220cd060..f97223750a1 100644
--- a/storage/ndb/src/mgmsrv/Services.hpp
+++ b/storage/ndb/src/mgmsrv/Services.hpp
@@ -79,6 +79,7 @@ public:
void start(Parser_t::Context &ctx, const class Properties &args);
void startAll(Parser_t::Context &ctx, const class Properties &args);
void bye(Parser_t::Context &ctx, const class Properties &args);
+ void endSession(Parser_t::Context &ctx, const class Properties &args);
void setLogLevel(Parser_t::Context &ctx, const class Properties &args);
void setClusterLogLevel(Parser_t::Context &ctx,
const class Properties &args);
diff --git a/storage/ndb/src/mgmsrv/main.cpp b/storage/ndb/src/mgmsrv/main.cpp
index f0c2ac298a5..5960a3517b5 100644
--- a/storage/ndb/src/mgmsrv/main.cpp
+++ b/storage/ndb/src/mgmsrv/main.cpp
@@ -132,6 +132,7 @@ static MgmGlobals *glob= 0;
* Global variables
*/
bool g_StopServer;
+bool g_RestartServer;
extern EventLogger g_eventLogger;
extern int global_mgmt_server_check;
@@ -191,7 +192,22 @@ static void usage()
*/
int main(int argc, char** argv)
{
+ int mgm_connect_result;
+
NDB_INIT(argv[0]);
+
+ const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+
+ int ho_error;
+#ifndef DBUG_OFF
+ opt_debug= "d:t:O,/tmp/ndb_mgmd.trace";
+#endif
+ if ((ho_error=handle_options(&argc, &argv, my_long_options,
+ ndb_std_get_one_option)))
+ exit(ho_error);
+
+start:
glob= new MgmGlobals;
/**
@@ -204,17 +220,6 @@ int main(int argc, char** argv)
#endif
global_mgmt_server_check = 1;
-
- const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
- load_defaults("my",load_default_groups,&argc,&argv);
-
- int ho_error;
-#ifndef DBUG_OFF
- opt_debug= "d:t:O,/tmp/ndb_mgmd.trace";
-#endif
- if ((ho_error=handle_options(&argc, &argv, my_long_options,
- ndb_std_get_one_option)))
- exit(ho_error);
if (opt_interactive ||
opt_non_interactive ||
@@ -293,34 +298,12 @@ int main(int argc, char** argv)
goto error_end;
}
- /* Construct a fake connectstring to connect back to ourselves */
- char connect_str[20];
- if(!opt_connect_str) {
- snprintf(connect_str,20,"localhost:%u",glob->mgmObject->getPort());
- opt_connect_str= connect_str;
- }
- glob->mgmObject->set_connect_string(opt_connect_str);
-
if(!glob->mgmObject->check_start()){
ndbout_c("Unable to check start management server.");
ndbout_c("Probably caused by illegal initial configuration file.");
goto error_end;
}
- /*
- * Connect back to ourselves so we can use mgmapi to fetch
- * config info
- */
- int mgm_connect_result;
- mgm_connect_result = glob->mgmObject->get_config_retriever()->
- do_connect(0,0,0);
-
- if(mgm_connect_result<0) {
- ndbout_c("Unable to connect to our own ndb_mgmd (Error %d)",
- mgm_connect_result);
- ndbout_c("This is probably a bug.");
- }
-
if (opt_daemon) {
// Become a daemon
char *lockfile= NdbConfig_PidFileName(glob->localNodeId);
@@ -361,6 +344,7 @@ int main(int argc, char** argv)
g_eventLogger.info(msg);
g_StopServer = false;
+ g_RestartServer= false;
glob->socketServer->startServer();
#if ! defined NDB_OSE && ! defined NDB_SOFTOSE
@@ -378,14 +362,19 @@ int main(int argc, char** argv)
while(g_StopServer != true)
NdbSleep_MilliSleep(500);
}
-
- g_eventLogger.info("Shutting down server...");
+
+ if(g_RestartServer)
+ g_eventLogger.info("Restarting server...");
+ else
+ g_eventLogger.info("Shutting down server...");
glob->socketServer->stopServer();
- glob->mgmObject->get_config_retriever()->disconnect();
+ // We disconnect from the ConfigRetreiver mgmd when we delete glob below
glob->socketServer->stopSessions(true);
g_eventLogger.info("Shutdown complete");
the_end:
delete glob;
+ if(g_RestartServer)
+ goto start;
ndb_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
return 0;
error_end:
diff --git a/storage/ndb/tools/ndb_size.pl b/storage/ndb/tools/ndb_size.pl
index e0085c619f0..c285a7590fd 100644
--- a/storage/ndb/tools/ndb_size.pl
+++ b/storage/ndb/tools/ndb_size.pl
@@ -147,7 +147,7 @@ foreach(@{$tables})
{
my $fixed= 1+$size;
my @dynamic=$dbh->selectrow_array("select avg(length(`"
- .$name.
+ .$name
."`)) from `".$table.'`');
$dynamic[0]=0 if !$dynamic[0];
@realsize= ($fixed,$fixed,ceil($dynamic[0]));
diff --git a/support-files/MySQL-shared-compat.spec.sh b/support-files/MySQL-shared-compat.spec.sh
index ffc96fd6fff..72ebf4d4d2b 100644
--- a/support-files/MySQL-shared-compat.spec.sh
+++ b/support-files/MySQL-shared-compat.spec.sh
@@ -23,16 +23,19 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59
# Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# For 5.0 and up, this is needed because of "libndbclient".
+%define _unpackaged_files_terminate_build 0
+
#
# Change this to match the version of the shared libs you want to include
#
%define version50 @MYSQL_NO_DASH_VERSION@
-%define version41 4.1.9
-%define version40 4.0.23
+%define version41 4.1.16
+%define version40 4.0.26
%define version3 3.23.58
Name: MySQL-shared-compat
-Packager: Lenz Grimmer <build@mysql.com>
+Packager: MySQL Product Engineering team <build@mysql.com>
Vendor: MySQL AB
License: GPL
Group: Applications/Databases
@@ -47,7 +50,7 @@ Summary: MySQL shared client libraries for MySQL %{version}, %{version41},
# We simply use the "MySQL-shared" subpackages as input sources instead of
# rebuilding all from source
Source0: MySQL-shared-%{version50}-0.%{_arch}.rpm
-Source1: MySQL-shared-%{version41}-0.%{_arch}.rpm
+Source1: MySQL-shared-%{version41}-1.%{_arch}.rpm
Source2: MySQL-shared-%{version40}-0.%{_arch}.rpm
Source3: MySQL-shared-%{version3}-1.%{_arch}.rpm
# No need to include the RPMs once more - they can be downloaded seperately
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index d33654d8810..e118289101e 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -14697,8 +14697,87 @@ static void test_opt_reconnect()
mysql_close(lmysql);
}
+/* Bug #16144: mysql_stmt_attr_get type error */
+
+static void test_bug16144()
+{
+ const my_bool flag_orig= (my_bool) 0xde;
+ my_bool flag= flag_orig;
+ MYSQL_STMT *stmt;
+ myheader("test_bug16144");
+
+ /* Check that attr_get returns correct data on little and big endian CPUs */
+ stmt= mysql_stmt_init(mysql);
+ mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
+ mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
+ DIE_UNLESS(flag == flag_orig);
+ mysql_stmt_close(stmt);
+}
/*
+ Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
+ field length"
+*/
+
+static void test_bug15613()
+{
+ MYSQL_STMT *stmt;
+ const char *stmt_text;
+ MYSQL_RES *metadata;
+ MYSQL_FIELD *field;
+ int rc;
+ myheader("test_bug15613");
+
+ /* I. Prepare the table */
+ rc= mysql_query(mysql, "set names latin1");
+ myquery(rc);
+ mysql_query(mysql, "drop table if exists t1");
+ rc= mysql_query(mysql,
+ "create table t1 (t text character set utf8, "
+ "tt tinytext character set utf8, "
+ "mt mediumtext character set utf8, "
+ "lt longtext character set utf8, "
+ "vl varchar(255) character set latin1,"
+ "vb varchar(255) character set binary,"
+ "vu varchar(255) character set utf8)");
+ myquery(rc);
+
+ stmt= mysql_stmt_init(mysql);
+
+ /* II. Check SELECT metadata */
+ stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
+ rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
+ metadata= mysql_stmt_result_metadata(stmt);
+ field= mysql_fetch_fields(metadata);
+ if (!opt_silent)
+ {
+ printf("Field lengths (client character set is latin1):\n"
+ "text character set utf8:\t\t%lu\n"
+ "tinytext character set utf8:\t\t%lu\n"
+ "mediumtext character set utf8:\t\t%lu\n"
+ "longtext character set utf8:\t\t%lu\n"
+ "varchar(255) character set latin1:\t%lu\n"
+ "varchar(255) character set binary:\t%lu\n"
+ "varchar(255) character set utf8:\t%lu\n",
+ field[0].length, field[1].length, field[2].length, field[3].length,
+ field[4].length, field[5].length, field[6].length);
+ }
+ DIE_UNLESS(field[0].length == 65535);
+ DIE_UNLESS(field[1].length == 255);
+ DIE_UNLESS(field[2].length == 16777215);
+ DIE_UNLESS(field[3].length == 4294967295UL);
+ DIE_UNLESS(field[4].length == 255);
+ DIE_UNLESS(field[5].length == 255);
+ DIE_UNLESS(field[6].length == 255);
+
+ /* III. Cleanup */
+ rc= mysql_query(mysql, "drop table t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "set names default");
+ myquery(rc);
+ mysql_stmt_close(stmt);
+}
+/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -14957,9 +15036,10 @@ static struct my_tests_st my_tests[]= {
{ "test_bug13488", test_bug13488 },
{ "test_bug13524", test_bug13524 },
{ "test_bug14845", test_bug14845 },
- { "test_bug15510", test_bug15510 },
{ "test_opt_reconnect", test_opt_reconnect },
-
+ { "test_bug15510", test_bug15510},
+ { "test_bug16144", test_bug16144 },
+ { "test_bug15613", test_bug15613 },
{ 0, 0 }
};
diff --git a/zlib/Makefile.am b/zlib/Makefile.am
index 11b1991fa62..71619ce40c1 100644
--- a/zlib/Makefile.am
+++ b/zlib/Makefile.am
@@ -16,6 +16,8 @@
# Process this file with automake to create Makefile.in
+INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include
+
pkglib_LTLIBRARIES=libz.la
libz_la_LDFLAGS= -version-info 3:3:2
diff --git a/zlib/README.MySQL b/zlib/README.MySQL
index 355dfb62d71..c17d3eeb6f9 100644
--- a/zlib/README.MySQL
+++ b/zlib/README.MySQL
@@ -5,3 +5,12 @@ original zlib distribution. You can find the original distribution at
http://www.gzip.org/zlib/
or
http://www.zlib.net/
+
+Revision history:
+
+20.01.2006. The following files were changed as part of #15787 fix:
+ makefile.am
+ gzio.c
+ zconf.h
+ README.mysql
+
diff --git a/zlib/gzio.c b/zlib/gzio.c
index 7e90f4928fc..afac5352323 100644
--- a/zlib/gzio.c
+++ b/zlib/gzio.c
@@ -7,10 +7,10 @@
/* @(#) $Id$ */
-#include <stdio.h>
-
#include "zutil.h"
+#include <stdio.h>
+
#ifdef NO_DEFLATE /* for compatibility with old definition */
# define NO_GZCOMPRESS
#endif
diff --git a/zlib/zconf.h b/zlib/zconf.h
index 03a9431c8be..d983fa3eed4 100644
--- a/zlib/zconf.h
+++ b/zlib/zconf.h
@@ -8,6 +8,10 @@
#ifndef ZCONF_H
#define ZCONF_H
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
@@ -284,7 +288,7 @@ typedef uLong FAR uLongf;
typedef Byte *voidp;
#endif
-#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+#ifdef HAVE_UNISTD_H
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS