Commit befbebcf authored by unknown's avatar unknown

Merge neptunus.(none):/home/msvensson/mysql/mysql-4.1

into  neptunus.(none):/home/msvensson/mysql/mysql-4.1-maint


client/mysqltest.c:
  Auto merged
Makefile.am:
  Manual merge
mysql-test/mysql-test-run.pl:
  Manual merge
parents e3a9d949 0fb76499
...@@ -26,7 +26,7 @@ all-local: $(TXT_FILES) ...@@ -26,7 +26,7 @@ all-local: $(TXT_FILES)
# make sure that "make install" installs the info page, too # make sure that "make install" installs the info page, too
# automake only seems to take care of this automatically, # automake only seems to take care of this automatically,
# if we're building the info page from texi directly. # if we're building the info page from texi directly.
install-data-hook: mysql.info install-data-hook: $(srcdir)/mysql.info
$(mkinstalldirs) $(DESTDIR)$(infodir) $(mkinstalldirs) $(DESTDIR)$(infodir)
$(INSTALL_DATA) $(srcdir)/mysql.info $(DESTDIR)$(infodir) $(INSTALL_DATA) $(srcdir)/mysql.info $(DESTDIR)$(infodir)
...@@ -39,23 +39,23 @@ CLEAN_FILES: $(TXT_FILES) ...@@ -39,23 +39,23 @@ CLEAN_FILES: $(TXT_FILES)
GT = $(srcdir)/Support/generate-text-files.pl GT = $(srcdir)/Support/generate-text-files.pl
../INSTALL-SOURCE: mysql.info $(GT) ../INSTALL-SOURCE: $(srcdir)/mysql.info $(GT)
perl -w $(GT) $< "installing-source" "windows-source-build" > $@ perl -w $(GT) $(srcdir)/mysql.info "installing-source" "windows-source-build" > $@
../INSTALL-WIN-SOURCE: mysql.info $(GT) ../INSTALL-WIN-SOURCE: $(srcdir)/mysql.info $(GT)
perl -w $(GT) $< "windows-source-build" "post-installation" > $@ perl -w $(GT) $(srcdir)/mysql.info "windows-source-build" "post-installation" > $@
# We put the description for the binary installation here so that # 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 # 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. # the toplevel by the script that makes the binary tar files.
INSTALL-BINARY: mysql.info $(GT) INSTALL-BINARY: $(srcdir)/mysql.info $(GT)
perl -w $(GT) $< "installing-binary" "installing-source" > $@ perl -w $(GT) $(srcdir)/mysql.info "installing-binary" "installing-source" > $@
../EXCEPTIONS-CLIENT: mysql.info $(GT) ../EXCEPTIONS-CLIENT: $(srcdir)/mysql.info $(GT)
perl -w $(GT) $< "mysql-floss-license-exception" "function-index" > $@ perl -w $(GT) $(srcdir)/mysql.info "mysql-floss-license-exception" "function-index" > $@
../support-files/MacOSX/ReadMe.txt: mysql.info $(GT) ../support-files/MacOSX/ReadMe.txt: $(srcdir)/mysql.info $(GT)
perl -w $(GT) $< "mac-os-x-installation" "netware-installation" > $@ perl -w $(GT) $(srcdir)/mysql.info "mac-os-x-installation" "netware-installation" > $@
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
...@@ -131,3 +131,9 @@ test-force-pl: ...@@ -131,3 +131,9 @@ test-force-pl:
./mysql-test-run.pl --force && \ ./mysql-test-run.pl --force && \
./mysql-test-run.pl --ps-protocol --force ./mysql-test-run.pl --ps-protocol --force
#used by autopush.pl to run memory based tests
test-force-pl-mem:
cd mysql-test; \
./mysql-test-run.pl --force --mem && \
./mysql-test-run.pl --ps-protocol --force --mem
...@@ -1448,20 +1448,20 @@ bdb_version_ok=yes ...@@ -1448,20 +1448,20 @@ bdb_version_ok=yes
]) ])
AC_DEFUN([MYSQL_TOP_BUILDDIR], [ AC_DEFUN([MYSQL_TOP_BUILDDIR], [
# Remove trailing "./" if any
[$1]=`echo $[$1] | sed -e 's,^\./,,'`
case "$[$1]" in case "$[$1]" in
/* ) ;; # don't do anything with an absolute path "bdb" | "$srcdir/bdb" | "$top_srcdir/bdb" | "$abs_top_srcdir/bdb" )
"$srcdir"/* )
# If BDB is under the source directory, we need to look under the # If BDB is under the source directory, we need to look under the
# build directory for bdb/build_unix. # build directory for bdb/build_unix.
# NOTE: I'm being lazy, and assuming the user did not specify [$1]="\$(top_builddir)/bdb"
# something like --with-berkeley-db=bdb (it would be missing "./").
[$1]="\$(top_builddir)/"`echo "$[$1]" | sed -e "s,^$srcdir/,,"`
;; ;;
/* ) ;; # Other absolute path is assume to be external BDB directory
* ) * )
AC_MSG_ERROR([The BDB directory must be directly under the MySQL source directory, or be specified using the full path. ('$srcdir'; '$[$1]')]) AC_MSG_ERROR([The BDB directory must be directly under the MySQL source directory, or be specified using the full path. ('$srcdir'; '$[$1]')])
;; ;;
esac esac
if test X"$[$1]" != "/" if test X"$[$1]" != X"/"
then then
[$1]=`echo $[$1] | sed -e 's,/$,,'` [$1]=`echo $[$1] | sed -e 's,/$,,'`
fi fi
...@@ -1493,7 +1493,7 @@ AC_DEFUN([MYSQL_CHECK_INNODB], [ ...@@ -1493,7 +1493,7 @@ AC_DEFUN([MYSQL_CHECK_INNODB], [
AC_MSG_RESULT([Using Innodb]) AC_MSG_RESULT([Using Innodb])
AC_DEFINE([HAVE_INNOBASE_DB], [1], [Using Innobase DB]) AC_DEFINE([HAVE_INNOBASE_DB], [1], [Using Innobase DB])
have_innodb="yes" have_innodb="yes"
innodb_includes="-I../innobase/include" innodb_includes="-I\$(top_builddir)/innobase/include -I\$(top_srcdir)/innobase/include"
innodb_system_libs="" innodb_system_libs=""
dnl Some libs are listed several times, in order for gcc to sort out dnl Some libs are listed several times, in order for gcc to sort out
dnl circular references. dnl circular references.
...@@ -1812,7 +1812,7 @@ AC_DEFUN([MYSQL_CHECK_NDBCLUSTER], [ ...@@ -1812,7 +1812,7 @@ AC_DEFUN([MYSQL_CHECK_NDBCLUSTER], [
AC_MSG_RESULT([Using NDB Cluster]) AC_MSG_RESULT([Using NDB Cluster])
AC_DEFINE([HAVE_NDBCLUSTER_DB], [1], [Using Ndb Cluster DB]) AC_DEFINE([HAVE_NDBCLUSTER_DB], [1], [Using Ndb Cluster DB])
have_ndbcluster="yes" have_ndbcluster="yes"
ndbcluster_includes="-I../ndb/include -I../ndb/include/ndbapi" ndbcluster_includes="-I\$(top_builddir)/ndb/include -I\$(top_srcdir)/ndb/include -I\$(top_srcdir)/ndb/include/ndbapi"
ndbcluster_libs="\$(top_builddir)/ndb/src/.libs/libndbclient.a" ndbcluster_libs="\$(top_builddir)/ndb/src/.libs/libndbclient.a"
ndbcluster_system_libs="" ndbcluster_system_libs=""
ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la" ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la"
......
...@@ -180,7 +180,7 @@ BEGIN { ...@@ -180,7 +180,7 @@ BEGIN {
t = types[i]; t = types[i];
if (modes[i] == "POINTER") { if (modes[i] == "POINTER") {
ndx = index(t, "*"); ndx = index(t, "*");
t = substr(types[i], 0, ndx - 2); t = substr(types[i], 1, ndx - 2);
} }
printf("\t%s\t%s;\n", t, vars[i]) >> HFILE printf("\t%s\t%s;\n", t, vars[i]) >> HFILE
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
Matt Wagner <matt@mysql.com> Matt Wagner <matt@mysql.com>
Monty Monty
Jani Jani
Holyfoot
*/ */
#define MTEST_VERSION "3.0" #define MTEST_VERSION "3.0"
...@@ -220,6 +221,12 @@ struct st_connection ...@@ -220,6 +221,12 @@ struct st_connection
MYSQL* util_mysql; MYSQL* util_mysql;
char *name; char *name;
MYSQL_STMT* stmt; MYSQL_STMT* stmt;
const char *cur_query;
int cur_query_len;
pthread_mutex_t mutex;
pthread_cond_t cond;
int query_done;
}; };
struct st_connection connections[128]; struct st_connection connections[128];
struct st_connection* cur_con, *next_con, *connections_end; struct st_connection* cur_con, *next_con, *connections_end;
...@@ -458,7 +465,6 @@ void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} ...@@ -458,7 +465,6 @@ void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {}
int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; } int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
#endif #endif
void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
int len); int len);
void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
...@@ -470,6 +476,56 @@ void handle_error(struct st_command*, ...@@ -470,6 +476,56 @@ void handle_error(struct st_command*,
void handle_no_error(struct st_command*); void handle_no_error(struct st_command*);
#ifdef EMBEDDED_LIBRARY
/*
send_one_query executes query in separate thread what is
necessary in embedded library to run 'send' in proper way.
This implementation doesn't handle errors returned
by mysql_send_query. It's technically possible, though
i don't see where it is needed.
*/
pthread_handler_decl(send_one_query, arg)
{
struct st_connection *cn= (struct st_connection*)arg;
mysql_thread_init();
VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len));
mysql_thread_end();
pthread_mutex_lock(&cn->mutex);
cn->query_done= 1;
VOID(pthread_cond_signal(&cn->cond));
pthread_mutex_unlock(&cn->mutex);
pthread_exit(0);
return 0;
}
static int do_send_query(struct st_connection *cn, const char *q, int q_len,
int flags)
{
pthread_t tid;
if (flags & QUERY_REAP_FLAG)
return mysql_send_query(&cn->mysql, q, q_len);
if (pthread_mutex_init(&cn->mutex, NULL) ||
pthread_cond_init(&cn->cond, NULL))
die("Error in the thread library");
cn->cur_query= q;
cn->cur_query_len= q_len;
cn->query_done= 0;
if (pthread_create(&tid, NULL, send_one_query, (void*)cn))
die("Cannot start new thread for query");
return 0;
}
#else /*EMBEDDED_LIBRARY*/
#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len)
#endif /*EMBEDDED_LIBRARY*/
void do_eval(DYNAMIC_STRING *query_eval, const char *query, void do_eval(DYNAMIC_STRING *query_eval, const char *query,
const char *query_end, my_bool pass_through_escape_chars) const char *query_end, my_bool pass_through_escape_chars)
...@@ -4506,7 +4562,6 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) ...@@ -4506,7 +4562,6 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
} }
/* /*
Run query using MySQL C API Run query using MySQL C API
...@@ -4523,10 +4578,11 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) ...@@ -4523,10 +4578,11 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
error - function will not return error - function will not return
*/ */
void run_query_normal(MYSQL *mysql, struct st_command *command, void run_query_normal(struct st_connection *cn, struct st_command *command,
int flags, char *query, int query_len, int flags, char *query, int query_len,
DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings) DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
{ {
MYSQL *mysql= &cn->mysql;
MYSQL_RES *res= 0; MYSQL_RES *res= 0;
int err= 0, counter= 0; int err= 0, counter= 0;
DBUG_ENTER("run_query_normal"); DBUG_ENTER("run_query_normal");
...@@ -4538,14 +4594,26 @@ void run_query_normal(MYSQL *mysql, struct st_command *command, ...@@ -4538,14 +4594,26 @@ void run_query_normal(MYSQL *mysql, struct st_command *command,
/* /*
Send the query Send the query
*/ */
if (mysql_send_query(mysql, query, query_len)) if (do_send_query(cn, query, query_len, flags))
{ {
handle_error(command, mysql_errno(mysql), mysql_error(mysql), handle_error(command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds); mysql_sqlstate(mysql), ds);
goto end; goto end;
} }
} }
#ifdef EMBEDDED_LIBRARY
/*
Here we handle 'reap' command, so we need to check if the
query's thread was finished and probably wait
*/
else if (flags & QUERY_REAP_FLAG)
{
pthread_mutex_lock(&cn->mutex);
while (!cn->query_done)
pthread_cond_wait(&cn->cond, &cn->mutex);
pthread_mutex_unlock(&cn->mutex);
}
#endif /*EMBEDDED_LIBRARY*/
if (!(flags & QUERY_REAP_FLAG)) if (!(flags & QUERY_REAP_FLAG))
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -5036,8 +5104,9 @@ int util_query(MYSQL* org_mysql, const char* query){ ...@@ -5036,8 +5104,9 @@ int util_query(MYSQL* org_mysql, const char* query){
*/ */
void run_query(MYSQL *mysql, struct st_command *command, int flags) void run_query(struct st_connection *cn, struct st_command *command, int flags)
{ {
MYSQL *mysql= &cn->mysql;
DYNAMIC_STRING *ds; DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_result; DYNAMIC_STRING ds_result;
DYNAMIC_STRING ds_warnings; DYNAMIC_STRING ds_warnings;
...@@ -5194,7 +5263,7 @@ void run_query(MYSQL *mysql, struct st_command *command, int flags) ...@@ -5194,7 +5263,7 @@ void run_query(MYSQL *mysql, struct st_command *command, int flags)
match_re(&ps_re, query)) match_re(&ps_re, query))
run_query_stmt(mysql, command, query, query_len, ds, &ds_warnings); run_query_stmt(mysql, command, query, query_len, ds, &ds_warnings);
else else
run_query_normal(mysql, command, flags, query, query_len, run_query_normal(cn, command, flags, query, query_len,
ds, &ds_warnings); ds, &ds_warnings);
if (sp_created) if (sp_created)
...@@ -5659,7 +5728,7 @@ int main(int argc, char **argv) ...@@ -5659,7 +5728,7 @@ int main(int argc, char **argv)
strmake(command->require_file, save_file, sizeof(save_file)); strmake(command->require_file, save_file, sizeof(save_file));
save_file[0]= 0; save_file[0]= 0;
} }
run_query(&cur_con->mysql, command, QUERY_REAP_FLAG|QUERY_SEND_FLAG); run_query(cur_con, command, QUERY_REAP_FLAG|QUERY_SEND_FLAG);
display_result_vertically= old_display_result_vertically; display_result_vertically= old_display_result_vertically;
command->last_argument= command->end; command->last_argument= command->end;
command_executed++; command_executed++;
...@@ -5690,7 +5759,7 @@ int main(int argc, char **argv) ...@@ -5690,7 +5759,7 @@ int main(int argc, char **argv)
strmake(command->require_file, save_file, sizeof(save_file)); strmake(command->require_file, save_file, sizeof(save_file));
save_file[0]= 0; save_file[0]= 0;
} }
run_query(&cur_con->mysql, command, flags); run_query(cur_con, command, flags);
command_executed++; command_executed++;
command->last_argument= command->end; command->last_argument= command->end;
break; break;
...@@ -5716,7 +5785,7 @@ int main(int argc, char **argv) ...@@ -5716,7 +5785,7 @@ int main(int argc, char **argv)
the query and read the result some time later when reap instruction the query and read the result some time later when reap instruction
is given on this connection. is given on this connection.
*/ */
run_query(&cur_con->mysql, command, QUERY_SEND_FLAG); run_query(cur_con, command, QUERY_SEND_FLAG);
command_executed++; command_executed++;
command->last_argument= command->end; command->last_argument= command->end;
break; break;
......
...@@ -46,12 +46,14 @@ do ...@@ -46,12 +46,14 @@ do
case $host_os in case $host_os in
netware* | modesto*) netware* | modesto*)
echo "$i/errmsg.sys: $i/errmsg.txt echo "$i/errmsg.sys: $i/errmsg.txt
\$(top_builddir)/extra/comp_err.linux -C\$(srcdir)/charsets/ $i/errmsg.txt $i/errmsg.sys" \ mkdir -p $i
\$(top_builddir)/extra/comp_err.linux -C\$(srcdir)/charsets/ \$(srcdir)/$i/errmsg.txt $i/errmsg.sys" \
>> $AVAILABLE_LANGUAGES_ERRORS_RULES >> $AVAILABLE_LANGUAGES_ERRORS_RULES
;; ;;
*) *)
echo "$i/errmsg.sys: $i/errmsg.txt echo "$i/errmsg.sys: $i/errmsg.txt
\$(top_builddir)/extra/comp_err -C\$(srcdir)/charsets/ $i/errmsg.txt $i/errmsg.sys" \ mkdir -p $i
\$(top_builddir)/extra/comp_err -C\$(srcdir)/charsets/ \$(srcdir)/$i/errmsg.txt $i/errmsg.sys" \
>> $AVAILABLE_LANGUAGES_ERRORS_RULES >> $AVAILABLE_LANGUAGES_ERRORS_RULES
;; ;;
esac esac
......
...@@ -281,12 +281,6 @@ typedef struct st_mysql ...@@ -281,12 +281,6 @@ typedef struct st_mysql
from mysql_stmt_close if close had to cancel result set of this object. from mysql_stmt_close if close had to cancel result set of this object.
*/ */
my_bool *unbuffered_fetch_owner; my_bool *unbuffered_fetch_owner;
/*
In embedded server it points to the statement that is processed
in the current query. We store some results directly in statement
fields then.
*/
struct st_mysql_stmt *current_stmt;
} MYSQL; } MYSQL;
typedef struct st_mysql_res { typedef struct st_mysql_res {
......
...@@ -154,7 +154,6 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned ...@@ -154,7 +154,6 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned
struct st_mysql_methods const * methods; struct st_mysql_methods const * methods;
void * thd; void * thd;
my_bool * unbuffered_fetch_owner; my_bool * unbuffered_fetch_owner;
struct st_mysql_stmt * current_stmt;
}; };
# 571 "mysql.h" # 571 "mysql.h"
struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_bind struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_bind
......
...@@ -4395,13 +4395,6 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) ...@@ -4395,13 +4395,6 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (result->data)
{
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
result->data= NULL;
result->rows= 0;
stmt->data_cursor= NULL;
}
if (stmt->update_max_length && !stmt->bind_result_done) if (stmt->update_max_length && !stmt->bind_result_done)
{ {
......
...@@ -31,8 +31,6 @@ INCLUDES = @MT_INCLUDES@ \ ...@@ -31,8 +31,6 @@ INCLUDES = @MT_INCLUDES@ \
## automake barfs if you don't use $(srcdir) or $(top_srcdir) in include ## automake barfs if you don't use $(srcdir) or $(top_srcdir) in include
include $(top_srcdir)/libmysql/Makefile.shared include $(top_srcdir)/libmysql/Makefile.shared
libmysql_dir = $(top_srcdir)/libmysql
libmysqlclient_r_la_SOURCES = $(target_sources) libmysqlclient_r_la_SOURCES = $(target_sources)
libmysqlclient_r_la_LIBADD = $(target_libadd) libmysqlclient_r_la_LIBADD = $(target_libadd)
libmysqlclient_r_la_LDFLAGS = $(target_ldflags) libmysqlclient_r_la_LDFLAGS = $(target_ldflags)
...@@ -40,7 +38,9 @@ libmysqlclient_r_la_LDFLAGS = $(target_ldflags) ...@@ -40,7 +38,9 @@ libmysqlclient_r_la_LDFLAGS = $(target_ldflags)
# This is called from the toplevel makefile # This is called from the toplevel makefile
link_sources: link_sources:
set -x; \ set -x; \
for f in `cd $(libmysql_dir) && echo *.[ch]`; do \ for d in $(top_srcdir)/libmysql $(top_builddir)/libmysql; do \
rm -f $$f; \ for f in `cd $$d && echo *.[ch]`; do \
@LN_CP_F@ $(libmysql_dir)/$$f $$f; \ rm -f $$f; \
@LN_CP_F@ $$d/$$f $$f; \
done; \
done done
...@@ -25,9 +25,11 @@ DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ ...@@ -25,9 +25,11 @@ DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
-DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
-DDATADIR="\"$(MYSQLDATAdir)\"" \ -DDATADIR="\"$(MYSQLDATAdir)\"" \
-DSHAREDIR="\"$(MYSQLSHAREdir)\"" -DSHAREDIR="\"$(MYSQLSHAREdir)\""
INCLUDES= @MT_INCLUDES@ @bdb_includes@ \ INCLUDES= @MT_INCLUDES@ @bdb_includes@ @innodb_includes@ @ndbcluster_includes@ \
-I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/include -I$(top_srcdir)/include \
-I$(top_srcdir)/sql -I$(top_srcdir)/sql/examples -I$(top_srcdir)/regex \ -I$(top_builddir)/sql -I$(top_srcdir)/sql \
-I$(top_srcdir)/sql/examples \
-I$(top_srcdir)/regex \
$(openssl_includes) @ZLIB_INCLUDES@ $(openssl_includes) @ZLIB_INCLUDES@
noinst_LIBRARIES = libmysqld_int.a noinst_LIBRARIES = libmysqld_int.a
...@@ -118,16 +120,28 @@ endif ...@@ -118,16 +120,28 @@ endif
#libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@ #libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@
#CLEANFILES = $(libmysqld_la_LIBADD) libmysqld.la #CLEANFILES = $(libmysqld_la_LIBADD) libmysqld.la
# This is called from the toplevel makefile # This is called from the toplevel makefile. If we can link now
# to an existing file in source, we do that, else we assume it
# will show up in the build tree eventually (generated file).
link_sources: link_sources:
set -x; \ set -x; \
for f in $(sqlsources); do \ for f in $(sqlsources); do \
rm -f $$f; \ rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \ if test -e $(top_srcdir)/sql/$$f ; \
then \
@LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \
else \
@LN_CP_F@ $(top_builddir)/sql/$$f $$f; \
fi ; \
done; \ done; \
for f in $(libmysqlsources); do \ for f in $(libmysqlsources); do \
rm -f $$f; \ rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/libmysql/$$f $$f; \ if test -e $(top_srcdir)/libmysql/$$f ; \
then \
@LN_CP_F@ $(top_srcdir)/libmysql/$$f $$f; \
else \
@LN_CP_F@ $(top_builddir)/libmysql/$$f $$f; \
fi ; \
done; \ done; \
for f in $(sqlexamplessources); do \ for f in $(sqlexamplessources); do \
rm -f $$f; \ rm -f $$f; \
......
...@@ -94,7 +94,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, ...@@ -94,7 +94,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
mysql->affected_rows= ~(my_ulonglong) 0; mysql->affected_rows= ~(my_ulonglong) 0;
mysql->field_count= 0; mysql->field_count= 0;
net->last_errno= 0; net->last_errno= 0;
mysql->current_stmt= stmt; thd->current_stmt= stmt;
thd->store_globals(); // Fix if more than one connect thd->store_globals(); // Fix if more than one connect
/* /*
...@@ -644,8 +644,8 @@ bool Protocol::send_fields(List<Item> *list, uint flag) ...@@ -644,8 +644,8 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
DBUG_RETURN(0); DBUG_RETURN(0);
field_count= list->elements; field_count= list->elements;
field_alloc= mysql->current_stmt ? &mysql->current_stmt->mem_root : field_alloc= thd->current_stmt ? &thd->current_stmt->mem_root :
&mysql->field_alloc; &mysql->field_alloc;
if (!(client_field= mysql->fields= if (!(client_field= mysql->fields=
(MYSQL_FIELD *)alloc_root(field_alloc, (MYSQL_FIELD *)alloc_root(field_alloc,
sizeof(MYSQL_FIELD) * field_count))) sizeof(MYSQL_FIELD) * field_count)))
...@@ -751,8 +751,8 @@ bool Protocol_prep::write() ...@@ -751,8 +751,8 @@ bool Protocol_prep::write()
{ {
MYSQL *mysql= thd->mysql; MYSQL *mysql= thd->mysql;
if (mysql->current_stmt) if (thd->current_stmt)
data= &mysql->current_stmt->result; data= &thd->current_stmt->result;
else else
{ {
if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
......
#
# This file is used from mysql-test-run.pl when choosing
# port numbers and directories to use for running mysqld.
#
use strict;
use Fcntl ':flock';
#
# Requested IDs are stored in a hash and released upon END.
#
my %mtr_unique_assigned_ids = ();
END {
while(my ($id,$file) = each(%mtr_unique_assigned_ids)) {
print "Autoreleasing $file:$id\n";
mtr_release_unique_id($file, $id);
}
}
#
# Require a unique, numerical ID, given a file name (where all
# requested IDs are stored), a minimum and a maximum value.
#
# We use flock to implement locking for the ID file and ignore
# possible problems arising from lack of support for it on
# some platforms (it should work on most, and the possible
# race condition would occur rarely). The proper solution for
# this is a daemon that manages IDs, of course.
#
# If no unique ID within the specified parameters can be
# obtained, return undef.
#
sub mtr_require_unique_id($$$) {
my $file = shift;
my $min = shift;
my $max = shift;
my $ret = undef;
my $changed = 0;
my $can_use_ps = `ps -e | grep '^[ ]*$$ '`;
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
chmod 0777, "$file.sem";
open SEM, ">", "$file.sem" or die "can't write to $file.sem";
flock SEM, LOCK_EX or die "can't lock $file.sem";
if(! -e $file) {
open FILE, ">", $file or die "can't create $file";
close FILE;
}
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
chmod 0777, $file;
open FILE, "+<", $file or die "can't open $file";
select undef,undef,undef,0.2;
seek FILE, 0, 0;
my %taken = ();
while(<FILE>) {
chomp;
my ($id, $pid) = split / /;
$taken{$id} = $pid;
if($can_use_ps) {
my $res = `ps -e | grep '^[ ]*$pid '`;
if(!$res) {
print "Ignoring slot $id used by missing process $pid.\n";
delete $taken{$id};
++$changed;
}
}
}
for(my $i=$min; $i<=$max; ++$i) {
if(! exists $taken{$i}) {
$ret = $i;
$taken{$i} = $$;
++$changed;
last;
}
}
if($changed) {
seek FILE, 0, 0;
truncate FILE, 0 or die "can't truncate $file";
for my $k (keys %taken) {
print FILE $k . ' ' . $taken{$k} . "\n";
}
}
close FILE;
flock SEM, LOCK_UN or warn "can't unlock $file.sem";
close SEM;
$mtr_unique_assigned_ids{$ret} = $file if defined $ret;
return $ret;
}
#
# Require a unique ID like above, but sleep if no ID can be
# obtained immediately.
#
sub mtr_require_unique_id_and_wait($$$) {
my $ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
while(! defined $ret) {
sleep 30;
$ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
print "Waiting for unique id to become available...\n" unless $ret;
}
return $ret;
}
#
# Release a unique ID.
#
sub mtr_release_unique_id($$) {
my $file = shift;
my $myid = shift;
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
open SEM, ">", "$file.sem" or die "can't write to $file.sem";
flock SEM, LOCK_EX or die "can't lock $file.sem";
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
if(! -e $file) {
open FILE, ">", $file or die "can't create $file";
close FILE;
}
open FILE, "+<", $file or die "can't open $file";
select undef,undef,undef,0.2;
seek FILE, 0, 0;
my %taken = ();
while(<FILE>) {
chomp;
my ($id, $pid) = split / /;
$taken{$id} = $pid;
}
delete $taken{$myid};
seek FILE, 0, 0;
truncate FILE, 0 or die "can't truncate $file";
for my $k (keys %taken) {
print FILE $k . ' ' . $taken{$k} . "\n";
}
close FILE;
flock SEM, LOCK_UN or warn "can't unlock $file.sem";
close SEM;
delete $mtr_unique_assigned_ids{$myid};
}
1;
...@@ -87,6 +87,7 @@ require "lib/mtr_diff.pl"; ...@@ -87,6 +87,7 @@ require "lib/mtr_diff.pl";
require "lib/mtr_match.pl"; require "lib/mtr_match.pl";
require "lib/mtr_misc.pl"; require "lib/mtr_misc.pl";
require "lib/mtr_stress.pl"; require "lib/mtr_stress.pl";
require "lib/mtr_unique.pl";
$Devel::Trace::TRACE= 1; $Devel::Trace::TRACE= 1;
...@@ -437,6 +438,7 @@ sub main () { ...@@ -437,6 +438,7 @@ sub main () {
mtr_exit(0); mtr_exit(0);
} }
############################################################################## ##############################################################################
# #
# Default settings # Default settings
...@@ -472,6 +474,16 @@ sub command_line_setup () { ...@@ -472,6 +474,16 @@ sub command_line_setup () {
# differs between operating systems and configuration, see # differs between operating systems and configuration, see
# http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html # http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html
# But a fairly safe range seems to be 5001 - 32767 # But a fairly safe range seems to be 5001 - 32767
# If so requested, we try to avail ourselves of a unique build thread number.
if ( $ENV{'MTR_BUILD_THREAD'} ) {
if ( lc($ENV{'MTR_BUILD_THREAD'}) eq 'auto' ) {
print "Requesting build thread... ";
$ENV{'MTR_BUILD_THREAD'} = mtr_require_unique_id_and_wait("/tmp/mysql-test-ports", 200, 299);
print "got ".$ENV{'MTR_BUILD_THREAD'}."\n";
}
}
if ( $ENV{'MTR_BUILD_THREAD'} ) if ( $ENV{'MTR_BUILD_THREAD'} )
{ {
# Up to two masters, up to three slaves # Up to two masters, up to three slaves
......
...@@ -820,3 +820,30 @@ b a ...@@ -820,3 +820,30 @@ b a
20 1 20 1
10 2 10 2
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2);
SELECT a + 1 AS num FROM t1 ORDER BY 30 - num;
num
3
2
SELECT CONCAT('test', a) AS str FROM t1 ORDER BY UPPER(str);
str
test1
test2
SELECT a + 1 AS num FROM t1 GROUP BY 30 - num;
num
3
2
SELECT a + 1 AS num FROM t1 HAVING 30 - num;
num
2
3
SELECT a + 1 AS num, num + 1 FROM t1;
ERROR 42S22: Unknown column 'num' in 'field list'
SELECT a + 1 AS num, (select num + 2 FROM t1 LIMIT 1) FROM t1;
num (select num + 2 FROM t1 LIMIT 1)
2 4
3 5
SELECT a.a + 1 AS num FROM t1 a JOIN t1 b ON num = b.a;
ERROR 42S22: Unknown column 'num' in 'on clause'
DROP TABLE t1;
...@@ -2981,3 +2981,35 @@ field1 field2 ...@@ -2981,3 +2981,35 @@ field1 field2
1 1 1 1
1 3 1 3
DROP TABLE t1, t2; DROP TABLE t1, t2;
CREATE TABLE t1(a int, INDEX (a));
INSERT INTO t1 VALUES (1), (3), (5), (7);
INSERT INTO t1 VALUES (NULL);
CREATE TABLE t2(a int);
INSERT INTO t2 VALUES (1),(2),(3);
EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 3
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index
SELECT a, a IN (SELECT a FROM t1) FROM t2;
a a IN (SELECT a FROM t1)
1 1
2 NULL
3 1
DROP TABLE t1,t2;
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
CREATE TABLE t2 AS SELECT
(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
FROM t1 WHERE a > '2000-01-01';
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`sub_a` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
SHOW CREATE TABLE t3;
Table Create Table
t3 CREATE TABLE `t3` (
`a` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1,t2,t3;
# This test doesn't work with the embedded version as this code
# assumes that one query is running while we are doing queries on
# a second connection.
# This would work if mysqltest run would be threaded and handle each
# connection in a separate thread.
#
-- source include/not_embedded.inc
-- source include/have_bdb.inc -- source include/have_bdb.inc
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
......
# This test doesn't work with the embedded version as this code
# assumes that one query is running while we are doing queries on
# a second connection.
# This would work if mysqltest run would be threaded and handle each
# connection in a separate thread.
#
-- source include/not_embedded.inc
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
connect (con2,localhost,root,,); connect (con2,localhost,root,,);
connection con1; connection con1;
......
...@@ -3,9 +3,6 @@ ...@@ -3,9 +3,6 @@
# We verify that we did not introduce a deadlock. # We verify that we did not introduce a deadlock.
# This is intended to mimick how mysqldump and innobackup work. # This is intended to mimick how mysqldump and innobackup work.
# This test doesn't work with the embedded server
-- source include/not_embedded.inc
# And it requires InnoDB # And it requires InnoDB
-- source include/have_innodb.inc -- source include/have_innodb.inc
......
-- source include/have_innodb.inc -- source include/have_innodb.inc
# Can't test this with embedded server
-- source include/not_embedded.inc
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
connect (con2,localhost,root,,); connect (con2,localhost,root,,);
......
-- source include/have_innodb.inc -- source include/have_innodb.inc
# Can't test this with embedded server
-- source include/not_embedded.inc
# #
# Check and select innodb lock type # Check and select innodb lock type
......
# This test doesn't work with the embedded version as this code
# assumes that one query is running while we are doing queries on
# a second connection.
# This would work if mysqltest run would be threaded and handle each
# connection in a separate thread.
#
-- source include/not_embedded.inc
--disable_warnings --disable_warnings
drop table if exists t1,t2; drop table if exists t1,t2;
--enable_warnings --enable_warnings
......
...@@ -34,6 +34,24 @@ ...@@ -34,6 +34,24 @@
--exec echo 'help' | $MYSQL > $MYSQLTEST_VARDIR/tmp/bug20328.tmp --exec echo 'help' | $MYSQL > $MYSQLTEST_VARDIR/tmp/bug20328.tmp
--exec echo 'help ' | $MYSQL > $MYSQLTEST_VARDIR/tmp/bug20328.tmp --exec echo 'help ' | $MYSQL > $MYSQLTEST_VARDIR/tmp/bug20328.tmp
#
# Bug #19216: Client crashes on long SELECT
#
--exec echo "select" > $MYSQLTEST_VARDIR/tmp/b19216.tmp
# 3400 * 20 makes 68000 columns that is more than the max number that can fit
# in a 16 bit number.
let $i= 3400;
while ($i)
{
--exec echo "'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'," >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
dec $i;
}
--exec echo "'b';" >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
--disable_query_log
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/b19216.tmp >/dev/null
--enable_query_log
# #
# Bug#17583: mysql drops connection when stdout is not writable # Bug#17583: mysql drops connection when stdout is not writable
# #
...@@ -51,4 +69,21 @@ select count(*) from t17583; ...@@ -51,4 +69,21 @@ select count(*) from t17583;
--exec echo "select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; " |$MYSQL test >&- --exec echo "select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; " |$MYSQL test >&-
drop table t17583; drop table t17583;
#
# Bug #19216: Client crashes on long SELECT
#
--exec echo "select" > $MYSQLTEST_VARDIR/tmp/b19216.tmp
# 3400 * 20 makes 68000 columns that is more than the max number that can fit
# in a 16 bit number.
let $i= 3400;
while ($i)
{
--exec echo "'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'," >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
dec $i;
}
--exec echo "'b';" >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
--disable_query_log
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/b19216.tmp >/dev/null
--enable_query_log
--echo End of 4.1 tests. --echo End of 4.1 tests.
...@@ -559,4 +559,20 @@ INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10); ...@@ -559,4 +559,20 @@ INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10);
DROP TABLE t1; DROP TABLE t1;
#
# Bug #22457: Column alias in ORDER BY works, but not if in an expression
#
CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2);
SELECT a + 1 AS num FROM t1 ORDER BY 30 - num;
SELECT CONCAT('test', a) AS str FROM t1 ORDER BY UPPER(str);
SELECT a + 1 AS num FROM t1 GROUP BY 30 - num;
SELECT a + 1 AS num FROM t1 HAVING 30 - num;
--error 1054
SELECT a + 1 AS num, num + 1 FROM t1;
SELECT a + 1 AS num, (select num + 2 FROM t1 LIMIT 1) FROM t1;
--error 1054
SELECT a.a + 1 AS num FROM t1 a JOIN t1 b ON num = b.a;
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
...@@ -2,10 +2,6 @@ ...@@ -2,10 +2,6 @@
# Test of rename table # Test of rename table
# #
# Test requires concurrent connections, which can't be tested on embedded
# server
-- source include/not_embedded.inc
--disable_warnings --disable_warnings
drop table if exists t0,t1,t2,t3,t4; drop table if exists t0,t1,t2,t3,t4;
# Clear up from other tests (to ensure that SHOW TABLES below is right) # Clear up from other tests (to ensure that SHOW TABLES below is right)
......
# Requires use of multiple simultaneous connections, not supported with # Uses GRANT commands that usually disabled in embedded server
# embedded server testing
-- source include/not_embedded.inc -- source include/not_embedded.inc
# #
......
# This test doesn't work with the embedded version as this code
# assumes that one query is running while we are doing queries on
# a second connection.
# This would work if mysqltest run would be threaded and handle each
# connection in a separate thread.
#
--source include/not_embedded.inc
# PS causes different statistics # PS causes different statistics
--disable_ps_protocol --disable_ps_protocol
......
...@@ -1948,4 +1948,37 @@ SELECT field1, field2 ...@@ -1948,4 +1948,37 @@ SELECT field1, field2
DROP TABLE t1, t2; DROP TABLE t1, t2;
#
# Bug #23478: not top-level IN subquery returning a non-empty result set
# with possible NULL values by index access from the outer query
#
CREATE TABLE t1(a int, INDEX (a));
INSERT INTO t1 VALUES (1), (3), (5), (7);
INSERT INTO t1 VALUES (NULL);
CREATE TABLE t2(a int);
INSERT INTO t2 VALUES (1),(2),(3);
EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
SELECT a, a IN (SELECT a FROM t1) FROM t2;
DROP TABLE t1,t2;
#
# Bug #11302: getObject() returns a String for a sub-query of type datetime
#
CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
CREATE TABLE t2 AS SELECT
(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
FROM t1 WHERE a > '2000-01-01';
SHOW CREATE TABLE t2;
CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
SHOW CREATE TABLE t3;
DROP TABLE t1,t2,t3;
# End of 4.1 tests # End of 4.1 tests
...@@ -7,6 +7,6 @@ ndbapiincludedir = "$(pkgincludedir)/ndb/ndbapi" ...@@ -7,6 +7,6 @@ ndbapiincludedir = "$(pkgincludedir)/ndb/ndbapi"
mgmapiincludedir = "$(pkgincludedir)/ndb/mgmapi" mgmapiincludedir = "$(pkgincludedir)/ndb/mgmapi"
INCLUDES = $(INCLUDES_LOC) INCLUDES = $(INCLUDES_LOC)
LDADD = $(LDADD_LOC) -L$(top_srcdir)/ndb/src/common/portlib -lmygcc LDADD = $(LDADD_LOC) -L$(top_builddir)/ndb/src/common/portlib -lmygcc
DEFS = @DEFS@ @NDB_DEFS@ $(DEFS_LOC) $(NDB_EXTRA_FLAGS) DEFS = @DEFS@ @NDB_DEFS@ $(DEFS_LOC) $(NDB_EXTRA_FLAGS)
NDB_CXXFLAGS=@ndb_cxxflags_fix@ $(NDB_CXXFLAGS_LOC) NDB_CXXFLAGS=@ndb_cxxflags_fix@ $(NDB_CXXFLAGS_LOC)
INCLUDES += \ INCLUDES += \
-I$(srcdir) -I$(top_srcdir)/include \ -I$(srcdir) \
-I$(top_builddir)/include \
-I$(top_builddir)/ndb/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include \
-I$(top_srcdir)/ndb/src/kernel/vm \ -I$(top_srcdir)/ndb/src/kernel/vm \
-I$(top_srcdir)/ndb/src/kernel/error \ -I$(top_srcdir)/ndb/src/kernel/error \
......
INCLUDES += \ INCLUDES += \
-I$(srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/ndb/include \ -I$(srcdir) \
-I$(top_builddir)/include \
-I$(top_builddir)/ndb/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/ndb/include \
-I$(top_srcdir)/ndb/include/kernel \ -I$(top_srcdir)/ndb/include/kernel \
-I$(top_srcdir)/ndb/include/transporter \ -I$(top_srcdir)/ndb/include/transporter \
-I$(top_srcdir)/ndb/include/debugger \ -I$(top_srcdir)/ndb/include/debugger \
......
...@@ -5,7 +5,10 @@ LDADD += $(top_builddir)/ndb/test/src/libNDBT.a \ ...@@ -5,7 +5,10 @@ LDADD += $(top_builddir)/ndb/test/src/libNDBT.a \
$(top_builddir)/mysys/libmysys.a \ $(top_builddir)/mysys/libmysys.a \
$(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/include \ INCLUDES += -I$(top_srcdir) \
-I$(top_builddir)/include \
-I$(top_builddir)/ndb/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include \
-I$(top_srcdir)/ndb/include/ndbapi \ -I$(top_srcdir)/ndb/include/ndbapi \
-I$(top_srcdir)/ndb/include/util \ -I$(top_srcdir)/ndb/include/util \
......
...@@ -5,7 +5,10 @@ LDADD += \ ...@@ -5,7 +5,10 @@ LDADD += \
$(top_builddir)/mysys/libmysys.a \ $(top_builddir)/mysys/libmysys.a \
$(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ -lmygcc $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ -lmygcc
INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \ INCLUDES += -I$(srcdir) \
-I$(top_builddir)/include \
-I$(top_builddir)/ndb/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include \
-I$(top_srcdir)/ndb/include/ndbapi \ -I$(top_srcdir)/ndb/include/ndbapi \
-I$(top_srcdir)/ndb/include/util \ -I$(top_srcdir)/ndb/include/util \
......
INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \ INCLUDES += -I$(srcdir) \
-I$(top_builddir)/include \
-I$(top_builddir)/ndb/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/ndb/include \ -I$(top_srcdir)/ndb/include \
-I$(top_srcdir)/ndb/include/util \ -I$(top_srcdir)/ndb/include/util \
-I$(top_srcdir)/ndb/include/portlib \ -I$(top_srcdir)/ndb/include/portlib \
......
...@@ -9,21 +9,21 @@ ndbd_SOURCES = main.cpp SimBlockList.cpp ...@@ -9,21 +9,21 @@ ndbd_SOURCES = main.cpp SimBlockList.cpp
include $(top_srcdir)/ndb/config/type_kernel.mk.am include $(top_srcdir)/ndb/config/type_kernel.mk.am
INCLUDES += \ INCLUDES += \
-Iblocks/cmvmi \ -I$(srcdir)/blocks/cmvmi \
-Iblocks/dbacc \ -I$(srcdir)/blocks/dbacc \
-Iblocks/dbdict \ -I$(srcdir)/blocks/dbdict \
-Iblocks/dbdih \ -I$(srcdir)/blocks/dbdih \
-Iblocks/dblqh \ -I$(srcdir)/blocks/dblqh \
-Iblocks/dbtc \ -I$(srcdir)/blocks/dbtc \
-Iblocks/dbtup \ -I$(srcdir)/blocks/dbtup \
-Iblocks/ndbfs \ -I$(srcdir)/blocks/ndbfs \
-Iblocks/ndbcntr \ -I$(srcdir)/blocks/ndbcntr \
-Iblocks/qmgr \ -I$(srcdir)/blocks/qmgr \
-Iblocks/trix \ -I$(srcdir)/blocks/trix \
-Iblocks/backup \ -I$(srcdir)/blocks/backup \
-Iblocks/dbutil \ -I$(srcdir)/blocks/dbutil \
-Iblocks/suma \ -I$(srcdir)/blocks/suma \
-Iblocks/dbtux -I$(srcdir)/blocks/dbtux
LDADD += \ LDADD += \
blocks/cmvmi/libcmvmi.a \ blocks/cmvmi/libcmvmi.a \
......
...@@ -1173,6 +1173,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, ...@@ -1173,6 +1173,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
for (row=data->data; row ; row = row->next,field++) for (row=data->data; row ; row = row->next,field++)
{ {
uchar *pos; uchar *pos;
/* fields count may be wrong */
DBUG_ASSERT ((field - result) < fields);
cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7); cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
field->catalog = strdup_root(alloc,(char*) row->data[0]); field->catalog = strdup_root(alloc,(char*) row->data[0]);
field->db = strdup_root(alloc,(char*) row->data[1]); field->db = strdup_root(alloc,(char*) row->data[1]);
......
...@@ -1761,10 +1761,37 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -1761,10 +1761,37 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
Item** res= find_item_in_list(this, thd->lex->current_select->item_list, Item** res= find_item_in_list(this, thd->lex->current_select->item_list,
&counter, REPORT_EXCEPT_NOT_FOUND, &counter, REPORT_EXCEPT_NOT_FOUND,
&not_used); &not_used);
if (res != (Item **)not_found_item && (*res)->type() == Item::FIELD_ITEM) if (res != (Item **)not_found_item)
{ {
set_field((*((Item_field**)res))->field); if ((*res)->type() == Item::FIELD_ITEM)
return 0; {
/*
It's an Item_field referencing another Item_field in the select
list.
use the field from the Item_field in the select list and leave
the Item_field instance in place.
*/
set_field((*((Item_field**)res))->field);
return 0;
}
else
{
/*
It's not an Item_field in the select list so we must make a new
Item_ref to point to the Item in the select list and replace the
Item_field created by the parser with the new Item_ref.
*/
Item_ref *rf= new Item_ref(db_name,table_name,field_name);
if (!rf)
return 1;
thd->change_item_tree(ref, rf);
/*
Because Item_ref never substitutes itself with other items
in Item_ref::fix_fields(), we can safely use the original
pointer to it even after fix_fields()
*/
return rf->fix_fields(thd, tables, ref) || rf->check_cols(1);
}
} }
} }
......
...@@ -391,6 +391,15 @@ enum Item_result Item_singlerow_subselect::result_type() const ...@@ -391,6 +391,15 @@ enum Item_result Item_singlerow_subselect::result_type() const
return engine->type(); return engine->type();
} }
/*
Don't rely on the result type to calculate field type.
Ask the engine instead.
*/
enum_field_types Item_singlerow_subselect::field_type() const
{
return engine->field_type();
}
void Item_singlerow_subselect::fix_length_and_dec() void Item_singlerow_subselect::fix_length_and_dec()
{ {
if ((max_columns= engine->cols()) == 1) if ((max_columns= engine->cols()) == 1)
...@@ -610,6 +619,7 @@ double Item_in_subselect::val() ...@@ -610,6 +619,7 @@ double Item_in_subselect::val()
*/ */
DBUG_ASSERT(0); DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
null_value= 0;
if (exec()) if (exec())
{ {
reset(); reset();
...@@ -625,6 +635,7 @@ double Item_in_subselect::val() ...@@ -625,6 +635,7 @@ double Item_in_subselect::val()
longlong Item_in_subselect::val_int() longlong Item_in_subselect::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
null_value= 0;
if (exec()) if (exec())
{ {
reset(); reset();
...@@ -645,6 +656,7 @@ String *Item_in_subselect::val_str(String *str) ...@@ -645,6 +656,7 @@ String *Item_in_subselect::val_str(String *str)
*/ */
DBUG_ASSERT(0); DBUG_ASSERT(0);
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
null_value= 0;
if (exec()) if (exec())
{ {
reset(); reset();
...@@ -1354,31 +1366,35 @@ int subselect_uniquesubquery_engine::prepare() ...@@ -1354,31 +1366,35 @@ int subselect_uniquesubquery_engine::prepare()
return 1; return 1;
} }
static Item_result set_row(List<Item> &item_list, Item *item, /*
Item_cache **row, bool *maybe_null) makes storage for the output values for the subquery and calcuates
their data and column types and their nullability.
*/
void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
{ {
Item_result res_type= STRING_RESULT;
Item *sel_item; Item *sel_item;
List_iterator_fast<Item> li(item_list); List_iterator_fast<Item> li(item_list);
res_type= STRING_RESULT;
res_field_type= FIELD_TYPE_VAR_STRING;
for (uint i= 0; (sel_item= li++); i++) for (uint i= 0; (sel_item= li++); i++)
{ {
item->max_length= sel_item->max_length; item->max_length= sel_item->max_length;
res_type= sel_item->result_type(); res_type= sel_item->result_type();
res_field_type= sel_item->field_type();
item->decimals= sel_item->decimals; item->decimals= sel_item->decimals;
*maybe_null= sel_item->maybe_null; maybe_null= sel_item->maybe_null;
if (!(row[i]= Item_cache::get_cache(res_type))) if (!(row[i]= Item_cache::get_cache(res_type)))
return STRING_RESULT; // we should return something return;
row[i]->setup(sel_item); row[i]->setup(sel_item);
} }
if (item_list.elements > 1) if (item_list.elements > 1)
res_type= ROW_RESULT; res_type= ROW_RESULT;
return res_type;
} }
void subselect_single_select_engine::fix_length_and_dec(Item_cache **row) void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
{ {
DBUG_ASSERT(row || select_lex->item_list.elements==1); DBUG_ASSERT(row || select_lex->item_list.elements==1);
res_type= set_row(select_lex->item_list, item, row, &maybe_null); set_row(select_lex->item_list, row);
item->collation.set(row[0]->collation); item->collation.set(row[0]->collation);
if (cols() != 1) if (cols() != 1)
maybe_null= 0; maybe_null= 0;
...@@ -1390,13 +1406,14 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row) ...@@ -1390,13 +1406,14 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row)
if (unit->first_select()->item_list.elements == 1) if (unit->first_select()->item_list.elements == 1)
{ {
res_type= set_row(unit->types, item, row, &maybe_null); set_row(unit->types, row);
item->collation.set(row[0]->collation); item->collation.set(row[0]->collation);
} }
else else
{ {
bool fake= 0; bool maybe_null_saved= maybe_null;
res_type= set_row(unit->types, item, row, &fake); set_row(unit->types, row);
maybe_null= maybe_null_saved;
} }
} }
......
...@@ -142,6 +142,7 @@ public: ...@@ -142,6 +142,7 @@ public:
longlong val_int (); longlong val_int ();
String *val_str (String *); String *val_str (String *);
enum Item_result result_type() const; enum Item_result result_type() const;
enum_field_types field_type() const;
void fix_length_and_dec(); void fix_length_and_dec();
uint cols(); uint cols();
...@@ -273,6 +274,7 @@ protected: ...@@ -273,6 +274,7 @@ protected:
THD *thd; /* pointer to current THD */ THD *thd; /* pointer to current THD */
Item_subselect *item; /* item, that use this engine */ Item_subselect *item; /* item, that use this engine */
enum Item_result res_type; /* type of results */ enum Item_result res_type; /* type of results */
enum_field_types res_field_type; /* column type of the results */
bool maybe_null; /* may be null (first item in select) */ bool maybe_null; /* may be null (first item in select) */
public: public:
...@@ -282,6 +284,7 @@ public: ...@@ -282,6 +284,7 @@ public:
result= res; result= res;
item= si; item= si;
res_type= STRING_RESULT; res_type= STRING_RESULT;
res_field_type= FIELD_TYPE_VAR_STRING;
maybe_null= 0; maybe_null= 0;
} }
virtual ~subselect_engine() {}; // to satisfy compiler virtual ~subselect_engine() {}; // to satisfy compiler
...@@ -296,6 +299,7 @@ public: ...@@ -296,6 +299,7 @@ public:
virtual uint cols()= 0; /* return number of columnss in select */ virtual uint cols()= 0; /* return number of columnss in select */
virtual uint8 uncacheable()= 0; /* query is uncacheable */ virtual uint8 uncacheable()= 0; /* query is uncacheable */
enum Item_result type() { return res_type; } enum Item_result type() { return res_type; }
enum_field_types field_type() { return res_field_type; }
virtual void exclude()= 0; virtual void exclude()= 0;
bool may_be_null() { return maybe_null; }; bool may_be_null() { return maybe_null; };
virtual table_map upper_select_const_tables()= 0; virtual table_map upper_select_const_tables()= 0;
...@@ -303,6 +307,9 @@ public: ...@@ -303,6 +307,9 @@ public:
virtual void print(String *str)= 0; virtual void print(String *str)= 0;
virtual int change_item(Item_subselect *si, select_subselect *result)= 0; virtual int change_item(Item_subselect *si, select_subselect *result)= 0;
virtual bool no_tables()= 0; virtual bool no_tables()= 0;
protected:
void set_row(List<Item> &item_list, Item_cache **row);
}; };
......
...@@ -43,7 +43,7 @@ bool Protocol_prep::net_store_data(const char *from, uint length) ...@@ -43,7 +43,7 @@ bool Protocol_prep::net_store_data(const char *from, uint length)
packet->realloc(packet_length+9+length)) packet->realloc(packet_length+9+length))
return 1; return 1;
char *to=(char*) net_store_length((char*) packet->ptr()+packet_length, char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
(ulonglong) length); length);
memcpy(to,from,length); memcpy(to,from,length);
packet->length((uint) (to+length-packet->ptr())); packet->length((uint) (to+length-packet->ptr()));
return 0; return 0;
...@@ -297,8 +297,8 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message) ...@@ -297,8 +297,8 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
buff[0]=0; // No fields buff[0]=0; // No fields
pos=net_store_length(buff+1,(ulonglong) affected_rows); pos=net_store_length(buff+1,affected_rows);
pos=net_store_length(pos, (ulonglong) id); pos=net_store_length(pos, id);
if (thd->client_capabilities & CLIENT_PROTOCOL_41) if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{ {
DBUG_PRINT("info", DBUG_PRINT("info",
...@@ -416,7 +416,7 @@ bool send_old_password_request(THD *thd) ...@@ -416,7 +416,7 @@ bool send_old_password_request(THD *thd)
ulonglong for bigger numbers. ulonglong for bigger numbers.
*/ */
char *net_store_length(char *pkg, uint length) static char *net_store_length_fast(char *pkg, uint length)
{ {
uchar *packet=(uchar*) pkg; uchar *packet=(uchar*) pkg;
if (length < 251) if (length < 251)
...@@ -439,7 +439,7 @@ char *net_store_length(char *pkg, uint length) ...@@ -439,7 +439,7 @@ char *net_store_length(char *pkg, uint length)
char *net_store_data(char *to,const char *from, uint length) char *net_store_data(char *to,const char *from, uint length)
{ {
to=net_store_length(to,length); to=net_store_length_fast(to,length);
memcpy(to,from,length); memcpy(to,from,length);
return to+length; return to+length;
} }
...@@ -448,7 +448,7 @@ char *net_store_data(char *to,int32 from) ...@@ -448,7 +448,7 @@ char *net_store_data(char *to,int32 from)
{ {
char buff[20]; char buff[20];
uint length=(uint) (int10_to_str(from,buff,10)-buff); uint length=(uint) (int10_to_str(from,buff,10)-buff);
to=net_store_length(to,length); to=net_store_length_fast(to,length);
memcpy(to,buff,length); memcpy(to,buff,length);
return to+length; return to+length;
} }
...@@ -457,7 +457,7 @@ char *net_store_data(char *to,longlong from) ...@@ -457,7 +457,7 @@ char *net_store_data(char *to,longlong from)
{ {
char buff[22]; char buff[22];
uint length=(uint) (longlong10_to_str(from,buff,10)-buff); uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
to=net_store_length(to,length); to=net_store_length_fast(to,length);
memcpy(to,buff,length); memcpy(to,buff,length);
return to+length; return to+length;
} }
...@@ -520,7 +520,7 @@ bool Protocol::send_fields(List<Item> *list, uint flag) ...@@ -520,7 +520,7 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
if (flag & 1) if (flag & 1)
{ // Packet with number of elements { // Packet with number of elements
char *pos=net_store_length(buff, (uint) list->elements); char *pos=net_store_length(buff, list->elements);
(void) my_net_write(&thd->net, buff,(uint) (pos-buff)); (void) my_net_write(&thd->net, buff,(uint) (pos-buff));
} }
...@@ -648,7 +648,7 @@ bool Protocol::send_records_num(List<Item> *list, ulonglong records) ...@@ -648,7 +648,7 @@ bool Protocol::send_records_num(List<Item> *list, ulonglong records)
{ {
char *pos; char *pos;
char buff[20]; char buff[20];
pos=net_store_length(buff, (uint) list->elements); pos=net_store_length(buff, list->elements);
pos=net_store_length(pos, records); pos=net_store_length(pos, records);
return my_net_write(&thd->net, buff,(uint) (pos-buff)); return my_net_write(&thd->net, buff,(uint) (pos-buff));
} }
......
...@@ -177,7 +177,6 @@ void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L, ...@@ -177,7 +177,6 @@ void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
const char *info=0); const char *info=0);
void send_eof(THD *thd, bool no_flush=0); void send_eof(THD *thd, bool no_flush=0);
bool send_old_password_request(THD *thd); bool send_old_password_request(THD *thd);
char *net_store_length(char *packet,uint length);
char *net_store_data(char *to,const char *from, uint length); char *net_store_data(char *to,const char *from, uint length);
char *net_store_data(char *to,int32 from); char *net_store_data(char *to,int32 from);
char *net_store_data(char *to,longlong from); char *net_store_data(char *to,longlong from);
......
...@@ -686,6 +686,12 @@ public: ...@@ -686,6 +686,12 @@ public:
char *extra_data; char *extra_data;
ulong extra_length; ulong extra_length;
String query_rest; String query_rest;
/*
In embedded server it points to the statement that is processed
in the current query. We store some results directly in statement
fields then.
*/
struct st_mysql_stmt *current_stmt;
#endif #endif
NET net; // client connection descriptor NET net; // client connection descriptor
MEM_ROOT warn_root; // For warnings and errors MEM_ROOT warn_root; // For warnings and errors
......
...@@ -170,6 +170,8 @@ necessary to develop MySQL client applications. ...@@ -170,6 +170,8 @@ necessary to develop MySQL client applications.
%package shared %package shared
Summary: MySQL - Shared libraries Summary: MySQL - Shared libraries
Group: Applications/Databases Group: Applications/Databases
Provides: mysql-shared
Obsoletes: mysql-shared
%description shared %description shared
This package contains the shared libraries (*.so*) which certain This package contains the shared libraries (*.so*) which certain
...@@ -317,7 +319,10 @@ then ...@@ -317,7 +319,10 @@ then
cp -fp config.log "$MYSQL_MAXCONFLOG_DEST" cp -fp config.log "$MYSQL_MAXCONFLOG_DEST"
fi fi
make -i test-force || true ( cd mysql-test
perl ./mysql-test-run.pl --force --report-features
perl ./mysql-test-run.pl --force --ps-protocol
true )
# Save mysqld-max # Save mysqld-max
./libtool --mode=execute cp sql/mysqld sql/mysqld-max ./libtool --mode=execute cp sql/mysqld sql/mysqld-max
...@@ -380,7 +385,10 @@ then ...@@ -380,7 +385,10 @@ then
cp -fp config.log "$MYSQL_CONFLOG_DEST" cp -fp config.log "$MYSQL_CONFLOG_DEST"
fi fi
make -i test-force || true ( cd mysql-test
perl ./mysql-test-run.pl --force --report-features
perl ./mysql-test-run.pl --force --ps-protocol
true )
%install %install
RBR=$RPM_BUILD_ROOT RBR=$RPM_BUILD_ROOT
...@@ -716,6 +724,17 @@ fi ...@@ -716,6 +724,17 @@ fi
# itself - note that they must be ordered by date (important when # itself - note that they must be ordered by date (important when
# merging BK trees) # merging BK trees)
%changelog %changelog
* Thu Nov 16 2006 Joerg Bruehe <joerg@mysql.com>
- Explicitly note that the "MySQL-shared" RPMs (as built by MySQL AB)
replace "mysql-shared" (as distributed by SuSE) to allow easy upgrading
(bug#22081).
* Wed Nov 15 2006 Joerg Bruehe <joerg@mysql.com>
- Switch from "make test*" to explicit calls of the test suite,
so that "report features" can be used.
* Tue Jun 27 2006 Joerg Bruehe <joerg@mysql.com> * Tue Jun 27 2006 Joerg Bruehe <joerg@mysql.com>
- move "mysqldumpslow" from the client RPM to the server RPM (bug#20216) - move "mysqldumpslow" from the client RPM to the server RPM (bug#20216)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment