Commit 5ee7d7e7 authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Merge

parents cf640b91 0281a6b1
...@@ -16570,6 +16570,7 @@ GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ...@@ -16570,6 +16570,7 @@ GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
TO user_name [IDENTIFIED BY [PASSWORD] 'password'] TO user_name [IDENTIFIED BY [PASSWORD] 'password']
[, user_name [IDENTIFIED BY 'password'] ...] [, user_name [IDENTIFIED BY 'password'] ...]
[REQUIRE [REQUIRE
NONE |
[@{SSL| X509@}] [@{SSL| X509@}]
[CIPHER cipher [AND]] [CIPHER cipher [AND]]
[ISSUER issuer [AND]] [ISSUER issuer [AND]]
...@@ -17645,6 +17646,9 @@ mysql> GRANT ALL PRIVILEGES ON test.* TO root@@localhost ...@@ -17645,6 +17646,9 @@ mysql> GRANT ALL PRIVILEGES ON test.* TO root@@localhost
-> AND CIPHER "EDH-RSA-DES-CBC3-SHA"; -> AND CIPHER "EDH-RSA-DES-CBC3-SHA";
@end example @end example
Starting from MySQL 4.0.4 the @code{AND} keyword is optional between
@code{REQUIRE} options.
The order of the options does not matter, but no option can be specified The order of the options does not matter, but no option can be specified
twice. twice.
@end itemize @end itemize
...@@ -46618,7 +46622,8 @@ Copy this file to some directory searched by @code{ld}, such as ...@@ -46618,7 +46622,8 @@ Copy this file to some directory searched by @code{ld}, such as
@code{LD_LIBRARY_PATH} environment variable to point at the directory where @code{LD_LIBRARY_PATH} environment variable to point at the directory where
you have your UDF function files. The @code{dlopen} manual page tells you you have your UDF function files. The @code{dlopen} manual page tells you
which variable you should use on your system. You should set this in which variable you should use on your system. You should set this in
@code{mysql.server} or @code{safe_mysqld} and restart @code{mysqld}. @code{mysql.server} or @code{safe_mysqld} startup scripts and restart
@code{mysqld}.
After the library is installed, notify @code{mysqld} about the new After the library is installed, notify @code{mysqld} about the new
functions with these commands: functions with these commands:
...@@ -50386,6 +50391,29 @@ each individual 4.0.x release. ...@@ -50386,6 +50391,29 @@ each individual 4.0.x release.
@itemize @bullet @itemize @bullet
@item @item
@code{--log-binary=a.b.c} now properly strips of @code{.b.c}.
@item
@code{FLUSH LOGS} removed numerical extension for all future update logs.
@item
@code{GRANT ... REQUIRE} didn't store the SSL information in the
@code{mysql.user} table if SSL was not enabled in the server.
@item
@code{GRANT ... REQUIRE NONE} can now be used to remove SSL information.
@item
@code{AND} is not optional between @code{REQUIRE} options.
@item
@code{REQUIRE} options was not properly saved, which could cause strange
output in @code{SHOW GRANTS}.
@item
Fixed that @code{mysqld --help} reports right values for @code{--datadir} and
@code{--bind-address}.
@item
Fixed that one can drop UDF functions that didn't exists when mysqld was
started.
@item
Fixed core dump problem with @code{SHOW VARIABLES} on some 64 bit systems
(like Solaris sparc).
@item
Fixed a bug in my_getopt; --set-variable syntax didn't work for Fixed a bug in my_getopt; --set-variable syntax didn't work for
those options that didn't have a valid variable in my_option struct. those options that didn't have a valid variable in my_option struct.
This affected at least @code{default-table-type} option. This affected at least @code{default-table-type} option.
...@@ -51118,7 +51146,7 @@ not yet 100% confident in this code. ...@@ -51118,7 +51146,7 @@ not yet 100% confident in this code.
@itemize @bullet @itemize @bullet
@item @item
Changed @code{AND/OR} to report that they can return NULL. This fixes a Changed @code{AND/OR} to report that they can return NULL. This fixes a
small problem in @code{GROUP BY} on @code{AND/OR} expression that return bug in @code{GROUP BY} on @code{AND/OR} expression that return
@code{NULL}. @code{NULL}.
@item @item
Fixed a bug that @code{OPTIMIZE} of locked and modified MyISAM table, Fixed a bug that @code{OPTIMIZE} of locked and modified MyISAM table,
...@@ -701,13 +701,13 @@ AC_DEFUN(MYSQL_CHECK_VIO, [ ...@@ -701,13 +701,13 @@ AC_DEFUN(MYSQL_CHECK_VIO, [
]) ])
AC_DEFUN(MYSQL_FIND_OPENSSL, [ AC_DEFUN(MYSQL_FIND_OPENSSL, [
for d in /usr/ssl/include /usr/local/ssl/include /usr/include/openssl \ for d in /usr/ssl/include /usr/local/ssl/include /usr/include \
/usr/include/ssl /opt/ssl/include /opt/openssl/include \ /usr/include/ssl /opt/ssl/include /opt/openssl/include \
/usr/local/ssl/include/openssl /usr/local/include/openssl ; do /usr/local/ssl/include /usr/local/include ; do
if test -f $d/ssl.h ; then if test -f $d/openssl/ssl.h ; then
OPENSSL_INCLUDE=$d OPENSSL_INCLUDE=$d
fi fi
done done
for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \ for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \
/usr/lib /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do /usr/lib /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do
......
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
# This file is public domain and comes with NO WARRANTY of any kind # This file is public domain and comes with NO WARRANTY of any kind
INCLUDES = -I$(srcdir)/../include $(openssl_includes) \ INCLUDES = -I$(srcdir)/../include \
-I../include -I$(srcdir)/.. -I$(top_srcdir) \ -I../include -I$(srcdir)/.. -I$(top_srcdir) \
-I.. -I.. $(openssl_includes)
LIBS = @CLIENT_LIBS@ LIBS = @CLIENT_LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysql/libmysqlclient.la
bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \ bin_PROGRAMS = mysql mysqladmin mysqlcheck mysqlshow \
......
...@@ -19,15 +19,15 @@ BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h ...@@ -19,15 +19,15 @@ BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h
pkginclude_HEADERS = dbug.h m_string.h my_sys.h my_list.h \ pkginclude_HEADERS = dbug.h m_string.h my_sys.h my_list.h \
mysql.h mysql_com.h mysqld_error.h mysql_embed.h \ mysql.h mysql_com.h mysqld_error.h mysql_embed.h \
my_semaphore.h my_pthread.h my_no_pthread.h raid.h \ my_semaphore.h my_pthread.h my_no_pthread.h raid.h \
errmsg.h my_global.h my_net.h my_alloc.h\ errmsg.h my_global.h my_net.h my_alloc.h \
sslopt-longopts.h sslopt-usage.h \ my_getopt.h sslopt-longopts.h sslopt-usage.h \
sslopt-vars.h $(BUILT_SOURCES) sslopt-vars.h $(BUILT_SOURCES)
noinst_HEADERS = config-win.h config-os2.h \ noinst_HEADERS = config-win.h config-os2.h \
nisam.h heap.h merge.h my_bitmap.h\ nisam.h heap.h merge.h my_bitmap.h\
myisam.h myisampack.h myisammrg.h ft_global.h\ myisam.h myisampack.h myisammrg.h ft_global.h\
my_dir.h mysys_err.h my_base.h \ my_dir.h mysys_err.h my_base.h \
my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \
my_aes.h my_getopt.h my_tree.h hash.h thr_alarm.h \ my_aes.h my_tree.h hash.h thr_alarm.h \
thr_lock.h t_ctype.h violite.h md5.h mysql_version.h.in thr_lock.h t_ctype.h violite.h md5.h mysql_version.h.in
# mysql_version.h are generated # mysql_version.h are generated
......
...@@ -193,7 +193,14 @@ Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state); ...@@ -193,7 +193,14 @@ Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state);
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
/* This enumerator is used in parser - should be always visible */ /* This enumerator is used in parser - should be always visible */
enum SSL_type {SSL_TYPE_NONE, SSL_TYPE_ANY, SSL_TYPE_X509, SSL_TYPE_SPECIFIED}; enum SSL_type
{
SSL_TYPE_NOT_SPECIFIED= -1,
SSL_TYPE_NONE,
SSL_TYPE_ANY,
SSL_TYPE_X509,
SSL_TYPE_SPECIFIED
};
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
/* This structure is for every connection on both sides */ /* This structure is for every connection on both sides */
......
...@@ -8,8 +8,8 @@ link_sources: ...@@ -8,8 +8,8 @@ link_sources:
done; done;
DEFS = -DEMBEDDED_LIBRARY DEFS = -DEMBEDDED_LIBRARY
INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include $(openssl_includes) \ INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include -I$(srcdir) \
-I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir) -I$(top_srcdir)/client $(openssl_includes)
LIBS = @LIBS@ LIBS = @LIBS@
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS)
......
...@@ -37,10 +37,11 @@ which () ...@@ -37,10 +37,11 @@ which ()
continue 2 continue 2
fi fi
done done
echo "which: no $file in ($PATH)" echo "Fatal error: Cannot find program $file in $PATH" 1>&2
exit 1 exit 1
done done
IFS="$save_ifs" IFS="$save_ifs"
exit 0
} }
...@@ -68,7 +69,7 @@ sleep_until_file_created () ...@@ -68,7 +69,7 @@ sleep_until_file_created ()
do do
if [ -r $file ] if [ -r $file ]
then then
return return 0
fi fi
sleep 1 sleep 1
loop=`expr $loop - 1` loop=`expr $loop - 1`
...@@ -81,8 +82,10 @@ sleep_until_file_created () ...@@ -81,8 +82,10 @@ sleep_until_file_created ()
SED=sed SED=sed
BASENAME=`which basename | $SED q` BASENAME=`which basename`
if test $? != 0; then exit 1; fi
DIFF=`which diff | $SED q` DIFF=`which diff | $SED q`
if test $? != 0; then exit 1; fi
CAT=cat CAT=cat
CUT=cut CUT=cut
HEAD=head HEAD=head
...@@ -90,12 +93,15 @@ TAIL=tail ...@@ -90,12 +93,15 @@ TAIL=tail
ECHO=echo # use internal echo if possible ECHO=echo # use internal echo if possible
EXPR=expr # use internal if possible EXPR=expr # use internal if possible
FIND=find FIND=find
GCOV=`which gcov | $SED q` GCOV=`which gcov`
if test $? != 0; then exit 1; fi
PRINTF=printf PRINTF=printf
RM=rm RM=rm
TIME=`which time | $SED q` TIME=`which time`
if test $? != 0; then exit 1; fi
TR=tr TR=tr
XARGS=`which xargs | $SED q` XARGS=`which xargs`
if test $? != 0; then exit 1; fi
# Are we using a source or a binary distribution? # Are we using a source or a binary distribution?
...@@ -461,7 +467,9 @@ GPROF_DIR=$MYSQL_TMP_DIR/gprof ...@@ -461,7 +467,9 @@ GPROF_DIR=$MYSQL_TMP_DIR/gprof
GPROF_MASTER=$GPROF_DIR/master.gprof GPROF_MASTER=$GPROF_DIR/master.gprof
GPROF_SLAVE=$GPROF_DIR/slave.gprof GPROF_SLAVE=$GPROF_DIR/slave.gprof
TIMEFILE="$MYSQL_TEST_DIR/var/log/mysqltest-time" TIMEFILE="$MYSQL_TEST_DIR/var/log/mysqltest-time"
XTERM=`which xterm` if [ -n "$DO_CLIENT_GDB" -o -n "$DO_GDB" ] ; then
XTERM=`which xterm`
fi
#++ #++
# Function Definitions # Function Definitions
......
delete from mysql.user where user='mysqltest_1';
delete from mysql.db where user='mysqltest_1';
flush privileges;
grant select on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
grant delete on mysqltest.* to mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
GRANT SELECT, DELETE ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
revoke delete on mysqltest.* from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
grant select on mysqltest.* to mysqltest_1@localhost require NONE;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB";
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE ISSUER 'MySQL AB' SUBJECT 'testsubject' CIPHER 'EDH-RSA-DES-CBC3-SHA'
delete from mysql.user where user='mysqltest_1';
flush privileges;
#
# Test that SSL options works properly
#
delete from mysql.user where user='mysqltest_1';
delete from mysql.db where user='mysqltest_1';
flush privileges;
grant select on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA";
show grants for mysqltest_1@localhost;
grant delete on mysqltest.* to mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
revoke delete on mysqltest.* from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
grant select on mysqltest.* to mysqltest_1@localhost require NONE;
show grants for mysqltest_1@localhost;
grant USAGE on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA" AND SUBJECT "testsubject" ISSUER "MySQL AB";
show grants for mysqltest_1@localhost;
revoke all privileges on mysqltest.* from mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
delete from mysql.user where user='mysqltest_1';
flush privileges;
...@@ -19,10 +19,19 @@ ...@@ -19,10 +19,19 @@
#include <m_string.h> #include <m_string.h>
/* /*
Return a pointerto the extension of the filename Return a pointer to the extension of the filename.
The pointer points at the extension character (normally '.'))
If there isn't any extension, the pointer points at the end SYNOPSIS
ASCII(0) of the filename. fn_ext()
name Name of file
DESCRIPTION
The extension is defined as everything after the first extension character
(normally '.') after the directory name.
RETURN VALUES
Pointer to to the extension character. If there isn't any extension,
points at the end ASCII(0) of the filename.
*/ */
my_string fn_ext(const char *name) my_string fn_ext(const char *name)
...@@ -40,6 +49,6 @@ my_string fn_ext(const char *name) ...@@ -40,6 +49,6 @@ my_string fn_ext(const char *name)
if (!(gpos=strrchr(name,FNLIBCHAR))) if (!(gpos=strrchr(name,FNLIBCHAR)))
gpos=name; gpos=name;
#endif #endif
pos=strrchr(gpos,FN_EXTCHAR); pos=strchr(gpos,FN_EXTCHAR);
DBUG_RETURN (pos ? pos : strend(gpos)); DBUG_RETURN (pos ? pos : strend(gpos));
} /* fn_ext */ } /* fn_ext */
...@@ -130,6 +130,11 @@ lex_hash.h: lex.h gen_lex_hash.cc sql_yacc.h ...@@ -130,6 +130,11 @@ lex_hash.h: lex.h gen_lex_hash.cc sql_yacc.h
# Hack to ensure that lex_hash.h is built early # Hack to ensure that lex_hash.h is built early
sql_lex.o: lex_hash.h sql_lex.o: lex_hash.h
# For testing of udf_example.so; Works on platforms with gcc
# (This is not part of our build process but only provided as an example)
udf_example.so: udf_example.cc
$(CXXCOMPILE) -shared -o $@ $<
#distclean: #distclean:
# rm -f lex_hash.h # rm -f lex_hash.h
......
...@@ -251,6 +251,7 @@ static SYMBOL symbols[] = { ...@@ -251,6 +251,7 @@ static SYMBOL symbols[] = {
{ "NEW", SYM(NEW_SYM),0,0}, { "NEW", SYM(NEW_SYM),0,0},
{ "NCHAR", SYM(NCHAR_SYM),0,0}, { "NCHAR", SYM(NCHAR_SYM),0,0},
{ "NO", SYM(NO_SYM),0,0}, { "NO", SYM(NO_SYM),0,0},
{ "NONE", SYM(NONE_SYM),0,0},
{ "NOT", SYM(NOT),0,0}, { "NOT", SYM(NOT),0,0},
{ "NULL", SYM(NULL_SYM),0,0}, { "NULL", SYM(NULL_SYM),0,0},
{ "NUMERIC", SYM(NUMERIC_SYM),0,0}, { "NUMERIC", SYM(NUMERIC_SYM),0,0},
......
...@@ -108,11 +108,9 @@ MYSQL_LOG::~MYSQL_LOG() ...@@ -108,11 +108,9 @@ MYSQL_LOG::~MYSQL_LOG()
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
{ {
if (log_type == LOG_NORMAL) fn_format(new_name,log_name,mysql_data_home,"",4);
fn_format(new_name,log_name,mysql_data_home,"",4); if (log_type != LOG_NORMAL)
else
{ {
fn_format(new_name,log_name,mysql_data_home,"",4);
if (!fn_ext(log_name)[0]) if (!fn_ext(log_name)[0])
{ {
if (find_uniq_filename(new_name)) if (find_uniq_filename(new_name))
...@@ -798,7 +796,8 @@ void MYSQL_LOG::new_file(bool need_lock) ...@@ -798,7 +796,8 @@ void MYSQL_LOG::new_file(bool need_lock)
safe_mutex_assert_owner(&LOCK_log); safe_mutex_assert_owner(&LOCK_log);
safe_mutex_assert_owner(&LOCK_index); safe_mutex_assert_owner(&LOCK_index);
new_name_ptr= name; // Reuse old name if not binlog // Reuse old name if not binlog and not update log
new_name_ptr= name;
/* /*
Only rotate open logs that are marked non-rotatable Only rotate open logs that are marked non-rotatable
...@@ -806,12 +805,17 @@ void MYSQL_LOG::new_file(bool need_lock) ...@@ -806,12 +805,17 @@ void MYSQL_LOG::new_file(bool need_lock)
*/ */
if (!no_rotate) if (!no_rotate)
{ {
/*
If user hasn't specified an extension, generate a new log name
We have to do this here and not in open as we want to store the
new file name in the current binary log file.
*/
if (generate_new_name(new_name, name))
goto end;
new_name_ptr=new_name;
if (log_type == LOG_BIN) if (log_type == LOG_BIN)
{ {
if (generate_new_name(new_name, name))
goto end; /* Error; Continue using old log file */
new_name_ptr=new_name;
if (!no_auto_events) if (!no_auto_events)
{ {
/* /*
...@@ -823,9 +827,9 @@ void MYSQL_LOG::new_file(bool need_lock) ...@@ -823,9 +827,9 @@ void MYSQL_LOG::new_file(bool need_lock)
r.set_log_pos(this); r.set_log_pos(this);
/* /*
Becasue this log rotation could have been initiated by a master of Because this log rotation could have been initiated by a master of
the slave running with log-bin, we set the flag on rotate the slave running with log-bin, we set the flag on rotate
event to prevent inifinite log rotation loop event to prevent infinite log rotation loop
*/ */
if (thd->slave_thread) if (thd->slave_thread)
r.flags|= LOG_EVENT_FORCED_ROTATE_F; r.flags|= LOG_EVENT_FORCED_ROTATE_F;
...@@ -833,7 +837,7 @@ void MYSQL_LOG::new_file(bool need_lock) ...@@ -833,7 +837,7 @@ void MYSQL_LOG::new_file(bool need_lock)
bytes_written += r.get_event_len(); bytes_written += r.get_event_len();
} }
/* /*
Update needs to be signaled even if there is no rotate event Update needs to be signalled even if there is no rotate event
log rotation should give the waiting thread a signal to log rotation should give the waiting thread a signal to
discover EOF and move on to the next log. discover EOF and move on to the next log.
*/ */
......
...@@ -384,7 +384,7 @@ bool mysql_embedded=0; ...@@ -384,7 +384,7 @@ bool mysql_embedded=0;
bool mysql_embedded=1; bool mysql_embedded=1;
#endif #endif
char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc static char *opt_bin_logname = 0;
char *opt_relay_logname = 0, *opt_relaylog_index_name=0; char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION; char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION;
const char *first_keyword="first"; const char *first_keyword="first";
...@@ -395,6 +395,7 @@ ulong rpl_recovery_rank=0; ...@@ -395,6 +395,7 @@ ulong rpl_recovery_rank=0;
my_string mysql_unix_port=NULL, opt_mysql_tmpdir=NULL, mysql_tmpdir=NULL; my_string mysql_unix_port=NULL, opt_mysql_tmpdir=NULL, mysql_tmpdir=NULL;
ulong my_bind_addr; /* the address we bind to */ ulong my_bind_addr; /* the address we bind to */
char *my_bind_addr_str;
DATE_FORMAT dayord; DATE_FORMAT dayord;
double log_10[32]; /* 10 potences */ double log_10[32]; /* 10 potences */
I_List<THD> threads,thread_cache; I_List<THD> threads,thread_cache;
...@@ -1744,10 +1745,10 @@ bool open_log(MYSQL_LOG *log, const char *hostname, ...@@ -1744,10 +1745,10 @@ bool open_log(MYSQL_LOG *log, const char *hostname,
first change fn_format() to cut the file name if it's too long. first change fn_format() to cut the file name if it's too long.
*/ */
strmake(tmp,hostname,FN_REFLEN-5); strmake(tmp,hostname,FN_REFLEN-5);
strmov(strcend(tmp,'.'),extension); strmov(fn_ext(tmp),extension);
opt_name=tmp; opt_name=tmp;
} }
// get rid of extention if the log is binary to avoid problems // get rid of extension if the log is binary to avoid problems
if (type == LOG_BIN) if (type == LOG_BIN)
{ {
char *p = fn_ext(opt_name); char *p = fn_ext(opt_name);
...@@ -1814,7 +1815,7 @@ int main(int argc, char **argv) ...@@ -1814,7 +1815,7 @@ int main(int argc, char **argv)
if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0) if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
strmov(glob_hostname,"mysql"); strmov(glob_hostname,"mysql");
strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5); strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
strmov(strcend(pidfile_name,'.'),".pid"); // Add extension strmov(fn_ext(pidfile_name),".pid"); // Add proper extension
#ifndef DBUG_OFF #ifndef DBUG_OFF
strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS); strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
#else #else
...@@ -2077,16 +2078,6 @@ The server will not act as a slave."); ...@@ -2077,16 +2078,6 @@ The server will not act as a slave.");
} }
if (opt_bin_log) if (opt_bin_log)
{ {
if (!opt_bin_logname)
{
char tmp[FN_REFLEN];
/* TODO: The following should be using fn_format(); We just need to
first change fn_format() to cut the file name if it's too long.
*/
strmake(tmp,glob_hostname,FN_REFLEN-5);
strmov(strcend(tmp,'.'),"-bin");
opt_bin_logname=my_strdup(tmp,MYF(MY_WME));
}
open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
opt_binlog_index_name,LOG_BIN); opt_binlog_index_name,LOG_BIN);
using_update_log=1; using_update_log=1;
...@@ -2957,9 +2948,9 @@ struct my_option my_long_options[] = ...@@ -2957,9 +2948,9 @@ struct my_option my_long_options[] =
{"binlog-ignore-db", OPT_BINLOG_IGNORE_DB, {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
"Tells the master that updates to the given database should not be logged tothe binary log", "Tells the master that updates to the given database should not be logged tothe binary log",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"bind-address", OPT_BIND_ADDRESS, "Ip address to bind to", {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to",
(gptr*) &my_bind_addr, (gptr*) &my_bind_addr, 0, GET_STR, REQUIRED_ARG, 0, (gptr*) &my_bind_addr_str, (gptr*) &my_bind_addr_str, 0, GET_STR,
0, 0, 0, 0, 0}, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts", 0, 0, 0, {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __WIN__ #ifdef __WIN__
...@@ -3276,9 +3267,6 @@ struct my_option my_long_options[] = ...@@ -3276,9 +3267,6 @@ struct my_option my_long_options[] =
{"skip-locking", OPT_SKIP_LOCK, {"skip-locking", OPT_SKIP_LOCK,
"Deprecated option, use --skip-external-locking instead", "Deprecated option, use --skip-external-locking instead",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-external-locking", OPT_SKIP_LOCK, "Do not use system (external) locking",
(gptr*) &opt_external_locking, (gptr*) &opt_external_locking,
0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names", 0, 0, 0, {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"skip-name-resolve", OPT_SKIP_RESOLVE, {"skip-name-resolve", OPT_SKIP_RESOLVE,
......
...@@ -75,8 +75,6 @@ static int init_failsafe_rpl_thread(THD* thd) ...@@ -75,8 +75,6 @@ static int init_failsafe_rpl_thread(THD* thd)
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
thd->mysys_var=my_thread_var;
thd->dbug_thread_id=my_thread_id();
#if !defined(__WIN__) && !defined(OS2) #if !defined(__WIN__) && !defined(OS2)
sigset_t set; sigset_t set;
VOID(sigemptyset(&set)); // Get mask in use VOID(sigemptyset(&set)); // Get mask in use
......
...@@ -1539,8 +1539,6 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) ...@@ -1539,8 +1539,6 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
thd->mysys_var=my_thread_var;
thd->dbug_thread_id=my_thread_id();
#if !defined(__WIN__) && !defined(OS2) #if !defined(__WIN__) && !defined(OS2)
sigset_t set; sigset_t set;
VOID(sigemptyset(&set)); // Get mask in use VOID(sigemptyset(&set)); // Get mask in use
......
...@@ -64,10 +64,8 @@ class ACL_USER :public ACL_ACCESS ...@@ -64,10 +64,8 @@ class ACL_USER :public ACL_ACCESS
USER_RESOURCES user_resource; USER_RESOURCES user_resource;
char *user,*password; char *user,*password;
ulong salt[2]; ulong salt[2];
#ifdef HAVE_OPENSSL
enum SSL_type ssl_type; enum SSL_type ssl_type;
const char *ssl_cipher, *x509_issuer, *x509_subject; const char *ssl_cipher, *x509_issuer, *x509_subject;
#endif /* HAVE_OPENSSL */
}; };
...@@ -142,12 +140,27 @@ static void init_update_queries(void) ...@@ -142,12 +140,27 @@ static void init_update_queries(void)
uc_update_queries[SQLCOM_MULTI_UPDATE]=1; uc_update_queries[SQLCOM_MULTI_UPDATE]=1;
} }
int acl_init(bool dont_read_acl_tables) /*
Read grant privileges from the privilege tables in the 'mysql' database.
SYNOPSIS
acl_init()
dont_read_acl_tables Set to 1 if run with --skip-grant
RETURN VALUES
0 ok
1 Could not initialize grant's
*/
my_bool acl_init(bool dont_read_acl_tables)
{ {
THD *thd; THD *thd, *org_thd;
TABLE_LIST tables[3]; TABLE_LIST tables[3];
TABLE *table; TABLE *table;
READ_RECORD read_record_info; READ_RECORD read_record_info;
MYSQL_LOCK *lock;
my_bool return_val=1;
DBUG_ENTER("acl_init"); DBUG_ENTER("acl_init");
if (!acl_cache) if (!acl_cache)
...@@ -157,13 +170,15 @@ int acl_init(bool dont_read_acl_tables) ...@@ -157,13 +170,15 @@ int acl_init(bool dont_read_acl_tables)
if (dont_read_acl_tables) if (dont_read_acl_tables)
DBUG_RETURN(0); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */
/*
To be able to run this from boot, we allocate a temporary THD
*/
org_thd=current_thd; // Save for restore
if (!(thd=new THD)) if (!(thd=new THD))
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */
thd->store_globals();
acl_cache->clear(1); // Clear locked hostname cache acl_cache->clear(1); // Clear locked hostname cache
thd->version=refresh_version;
thd->mysys_var=my_thread_var;
thd->current_tablenr=0;
thd->open_tables=0;
thd->db= my_strdup("mysql",MYF(0)); thd->db= my_strdup("mysql",MYF(0));
thd->db_length=5; // Safety thd->db_length=5; // Safety
bzero((char*) &tables,sizeof(tables)); bzero((char*) &tables,sizeof(tables));
...@@ -176,22 +191,13 @@ int acl_init(bool dont_read_acl_tables) ...@@ -176,22 +191,13 @@ int acl_init(bool dont_read_acl_tables)
tables[0].db=tables[1].db=tables[2].db=thd->db; tables[0].db=tables[1].db=tables[2].db=thd->db;
if (open_tables(thd,tables)) if (open_tables(thd,tables))
{ goto end;
close_thread_tables(thd); /* purecov: inspected */
delete thd; /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
}
TABLE *ptr[3]; // Lock tables for quick update TABLE *ptr[3]; // Lock tables for quick update
ptr[0]= tables[0].table; ptr[0]= tables[0].table;
ptr[1]= tables[1].table; ptr[1]= tables[1].table;
ptr[2]= tables[2].table; ptr[2]= tables[2].table;
MYSQL_LOCK *lock=mysql_lock_tables(thd,ptr,3); if (!(lock=mysql_lock_tables(thd,ptr,3)))
if (!lock) goto end;
{
close_thread_tables(thd); /* purecov: inspected */
delete thd; /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
}
init_sql_alloc(&mem,1024,0); init_sql_alloc(&mem,1024,0);
init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0); init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0);
...@@ -259,7 +265,6 @@ int acl_init(bool dont_read_acl_tables) ...@@ -259,7 +265,6 @@ int acl_init(bool dont_read_acl_tables)
(uint) strlen(user.host.hostname) : 0); (uint) strlen(user.host.hostname) : 0);
if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */ if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
{ {
#ifdef HAVE_OPENSSL
char *ssl_type=get_field(&mem, table, 24); char *ssl_type=get_field(&mem, table, 24);
if (!ssl_type) if (!ssl_type)
user.ssl_type=SSL_TYPE_NONE; user.ssl_type=SSL_TYPE_NONE;
...@@ -273,7 +278,7 @@ int acl_init(bool dont_read_acl_tables) ...@@ -273,7 +278,7 @@ int acl_init(bool dont_read_acl_tables)
user.ssl_cipher= get_field(&mem, table, 25); user.ssl_cipher= get_field(&mem, table, 25);
user.x509_issuer= get_field(&mem, table, 26); user.x509_issuer= get_field(&mem, table, 26);
user.x509_subject= get_field(&mem, table, 27); user.x509_subject= get_field(&mem, table, 27);
#endif
char *ptr = get_field(&mem, table, 28); char *ptr = get_field(&mem, table, 28);
user.user_resource.questions=atoi(ptr); user.user_resource.questions=atoi(ptr);
ptr = get_field(&mem, table, 29); ptr = get_field(&mem, table, 29);
...@@ -286,9 +291,7 @@ int acl_init(bool dont_read_acl_tables) ...@@ -286,9 +291,7 @@ int acl_init(bool dont_read_acl_tables)
} }
else else
{ {
#ifdef HAVE_OPENSSL
user.ssl_type=SSL_TYPE_NONE; user.ssl_type=SSL_TYPE_NONE;
#endif
bzero(&(user.user_resource),sizeof(user.user_resource)); bzero(&(user.user_resource),sizeof(user.user_resource));
#ifndef TO_BE_REMOVED #ifndef TO_BE_REMOVED
if (table->fields <= 13) if (table->fields <= 13)
...@@ -346,12 +349,17 @@ int acl_init(bool dont_read_acl_tables) ...@@ -346,12 +349,17 @@ int acl_init(bool dont_read_acl_tables)
init_check_host(); init_check_host();
mysql_unlock_tables(thd, lock); mysql_unlock_tables(thd, lock);
initialized=1;
init_update_queries(); init_update_queries();
thd->version--; // Force close to free memory thd->version--; // Force close to free memory
return_val=0;
end:
close_thread_tables(thd); close_thread_tables(thd);
delete thd; delete thd;
initialized=1; if (org_thd)
DBUG_RETURN(0); org_thd->store_globals(); /* purecov: inspected */
DBUG_RETURN(return_val);
} }
...@@ -374,18 +382,18 @@ void acl_free(bool end) ...@@ -374,18 +382,18 @@ void acl_free(bool end)
/* Reload acl list if possible */ /* Reload acl list if possible */
void acl_reload(void) void acl_reload(THD *thd)
{ {
DYNAMIC_ARRAY old_acl_hosts,old_acl_users,old_acl_dbs; DYNAMIC_ARRAY old_acl_hosts,old_acl_users,old_acl_dbs;
MEM_ROOT old_mem; MEM_ROOT old_mem;
bool old_initialized; bool old_initialized;
DBUG_ENTER("acl_reload"); DBUG_ENTER("acl_reload");
if (current_thd && current_thd->locked_tables) if (thd && thd->locked_tables)
{ // Can't have locked tables here { // Can't have locked tables here
current_thd->lock=current_thd->locked_tables; thd->lock=thd->locked_tables;
current_thd->locked_tables=0; thd->locked_tables=0;
close_thread_tables(current_thd); close_thread_tables(thd);
} }
if ((old_initialized=initialized)) if ((old_initialized=initialized))
VOID(pthread_mutex_lock(&acl_cache->lock)); VOID(pthread_mutex_lock(&acl_cache->lock));
...@@ -399,7 +407,7 @@ void acl_reload(void) ...@@ -399,7 +407,7 @@ void acl_reload(void)
if (acl_init(0)) if (acl_init(0))
{ // Error. Revert to old list { // Error. Revert to old list
acl_free(); /* purecov: inspected */ acl_free(); /* purecov: inspected */
acl_hosts=old_acl_hosts; acl_hosts=old_acl_hosts;
acl_users=old_acl_users; acl_users=old_acl_users;
acl_dbs=old_acl_dbs; acl_dbs=old_acl_dbs;
...@@ -536,6 +544,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, ...@@ -536,6 +544,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
if X509 certificate attributes are OK if X509 certificate attributes are OK
*/ */
switch (acl_user->ssl_type) { switch (acl_user->ssl_type) {
case SSL_TYPE_NOT_SPECIFIED: // Impossible
case SSL_TYPE_NONE: /* SSL is not required to connect */ case SSL_TYPE_NONE: /* SSL is not required to connect */
user_access=acl_user->access; user_access=acl_user->access;
break; break;
...@@ -559,15 +568,17 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, ...@@ -559,15 +568,17 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
use. use.
*/ */
if (acl_user->ssl_cipher) if (acl_user->ssl_cipher)
{
DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'", DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'",
acl_user->ssl_cipher, acl_user->ssl_cipher,
SSL_get_cipher(vio->ssl_))); SSL_get_cipher(vio->ssl_)));
if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_))) if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_)))
user_access=acl_user->access; user_access=acl_user->access;
else else
{ {
user_access=NO_ACCESS; user_access=NO_ACCESS;
break; break;
}
} }
/* Prepare certificate (if exists) */ /* Prepare certificate (if exists) */
DBUG_PRINT("info",("checkpoint 1")); DBUG_PRINT("info",("checkpoint 1"));
...@@ -661,12 +672,16 @@ static void acl_update_user(const char *user, const char *host, ...@@ -661,12 +672,16 @@ static void acl_update_user(const char *user, const char *host,
acl_user->user_resource.updates=mqh->updates; acl_user->user_resource.updates=mqh->updates;
if (mqh->bits & 4) if (mqh->bits & 4)
acl_user->user_resource.connections=mqh->connections; acl_user->user_resource.connections=mqh->connections;
#ifdef HAVE_OPENSSL if (ssl_type != SSL_TYPE_NOT_SPECIFIED)
acl_user->ssl_type=ssl_type; {
acl_user->ssl_cipher=ssl_cipher; acl_user->ssl_type= ssl_type;
acl_user->x509_issuer=x509_issuer; acl_user->ssl_cipher= (ssl_cipher ? strdup_root(&mem,ssl_cipher) :
acl_user->x509_subject=x509_subject; 0);
#endif /* HAVE_OPENSSL */ acl_user->x509_issuer= (x509_issuer ? strdup_root(&mem,x509_issuer) :
0);
acl_user->x509_subject= (x509_subject ?
strdup_root(&mem,x509_subject) : 0);
}
if (password) if (password)
{ {
if (!password[0]) if (!password[0])
...@@ -701,12 +716,11 @@ static void acl_insert_user(const char *user, const char *host, ...@@ -701,12 +716,11 @@ static void acl_insert_user(const char *user, const char *host,
acl_user.user_resource = *mqh; acl_user.user_resource = *mqh;
acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user); acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user);
acl_user.hostname_length=(uint) strlen(acl_user.host.hostname); acl_user.hostname_length=(uint) strlen(acl_user.host.hostname);
#ifdef HAVE_OPENSSL acl_user.ssl_type= (ssl_type != SSL_TYPE_NOT_SPECIFIED ?
acl_user.ssl_type=ssl_type; ssl_type : SSL_TYPE_NONE);
acl_user.ssl_cipher=ssl_cipher; acl_user.ssl_cipher= ssl_cipher ? strdup_root(&mem,ssl_cipher) : 0;
acl_user.x509_issuer=x509_issuer; acl_user.x509_issuer= x509_issuer ? strdup_root(&mem,x509_issuer) : 0;
acl_user.x509_subject=x509_subject; acl_user.x509_subject=x509_subject ? strdup_root(&mem,x509_subject) : 0;
#endif /* HAVE_OPENSSL */
if (password) if (password)
{ {
acl_user.password=(char*) ""; // Just point at something acl_user.password=(char*) ""; // Just point at something
...@@ -1295,7 +1309,6 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, ...@@ -1295,7 +1309,6 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
DBUG_PRINT("info",("table->fields: %d",table->fields)); DBUG_PRINT("info",("table->fields: %d",table->fields));
if (table->fields >= 31) /* From 4.0.0 we have more fields */ if (table->fields >= 31) /* From 4.0.0 we have more fields */
{ {
#ifdef HAVE_OPENSSL
/* We write down SSL related ACL stuff */ /* We write down SSL related ACL stuff */
table->field[25]->store("",0); table->field[25]->store("",0);
table->field[26]->store("",0); table->field[26]->store("",0);
...@@ -1322,7 +1335,6 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, ...@@ -1322,7 +1335,6 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
default: default:
table->field[24]->store("",0); table->field[24]->store("",0);
} }
#endif /* HAVE_OPENSSL */
USER_RESOURCES mqh = thd->lex.mqh; USER_RESOURCES mqh = thd->lex.mqh;
if (mqh.bits & 1) if (mqh.bits & 1)
...@@ -2234,11 +2246,12 @@ void grant_free(void) ...@@ -2234,11 +2246,12 @@ void grant_free(void)
/* Init grant array if possible */ /* Init grant array if possible */
int grant_init (void) my_bool grant_init(void)
{ {
THD *thd; THD *thd, *org_thd;
TABLE_LIST tables[2]; TABLE_LIST tables[2];
int error = 0; MYSQL_LOCK *lock;
my_bool return_val= 1;
TABLE *t_table, *c_table; TABLE *t_table, *c_table;
DBUG_ENTER("grant_init"); DBUG_ENTER("grant_init");
...@@ -2247,15 +2260,14 @@ int grant_init (void) ...@@ -2247,15 +2260,14 @@ int grant_init (void)
(hash_free_key) free_grant_table,0); (hash_free_key) free_grant_table,0);
init_sql_alloc(&memex,1024,0); init_sql_alloc(&memex,1024,0);
/* Don't do anything if running with --skip-grant */
if (!initialized) if (!initialized)
DBUG_RETURN(0); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */
org_thd=current_thd;
if (!(thd=new THD)) if (!(thd=new THD))
DBUG_RETURN(1); /* purecov: deadcode */ DBUG_RETURN(1); /* purecov: deadcode */
thd->store_globals();
thd->version=refresh_version;
thd->mysys_var=my_thread_var;
thd->current_tablenr=0;
thd->open_tables=0;
thd->db= my_strdup("mysql",MYF(0)); thd->db= my_strdup("mysql",MYF(0));
thd->db_length=5; // Safety thd->db_length=5; // Safety
bzero((char*) &tables,sizeof(tables)); bzero((char*) &tables,sizeof(tables));
...@@ -2266,60 +2278,51 @@ int grant_init (void) ...@@ -2266,60 +2278,51 @@ int grant_init (void)
tables[0].db=tables[1].db=thd->db; tables[0].db=tables[1].db=thd->db;
if (open_tables(thd,tables)) if (open_tables(thd,tables))
{ // No grant tables goto end;
close_thread_tables(thd); /* purecov: deadcode */
delete thd; /* purecov: deadcode */
DBUG_RETURN(1); /* purecov: deadcode */
}
TABLE *ptr[2]; // Lock tables for quick update TABLE *ptr[2]; // Lock tables for quick update
ptr[0]= tables[0].table; ptr[0]= tables[0].table;
ptr[1]= tables[1].table; ptr[1]= tables[1].table;
MYSQL_LOCK *lock=mysql_lock_tables(thd,ptr,2); if (!(lock=mysql_lock_tables(thd,ptr,2)))
if (!lock) goto end;
{
close_thread_tables(thd); /* purecov: deadcode */
delete thd; /* purecov: deadcode */
DBUG_RETURN(1); /* purecov: deadcode */
}
t_table = tables[0].table; c_table = tables[1].table; t_table = tables[0].table; c_table = tables[1].table;
t_table->file->index_init(0); t_table->file->index_init(0);
if (t_table->file->index_first(t_table->record[0])) if (t_table->file->index_first(t_table->record[0]))
{ {
t_table->file->index_end(); t_table->file->index_end();
mysql_unlock_tables(thd, lock); goto end_unlock;
thd->version--; // Force close to free memory
close_thread_tables(thd);
delete thd;
DBUG_RETURN(0); // Empty table is ok!
} }
grant_option= TRUE; grant_option= TRUE;
t_table->file->index_end(); t_table->file->index_end();
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); /* Will be restored by org_thd->store_globals() */
my_pthread_setspecific_ptr(THR_MALLOC,&memex); my_pthread_setspecific_ptr(THR_MALLOC,&memex);
while (!error) do
{ {
GRANT_TABLE *mem_check; GRANT_TABLE *mem_check;
if (!(mem_check=new GRANT_TABLE(t_table,c_table)) || if (!(mem_check=new GRANT_TABLE(t_table,c_table)) ||
mem_check->ok() && hash_insert(&hash_tables,(byte*) mem_check)) mem_check->ok() && hash_insert(&hash_tables,(byte*) mem_check))
{ {
/* This could only happen if we are out memory */ /* This could only happen if we are out memory */
my_pthread_setspecific_ptr(THR_MALLOC,old_root); /* purecov: deadcode */
grant_option = FALSE; /* purecov: deadcode */ grant_option = FALSE; /* purecov: deadcode */
mysql_unlock_tables(thd, lock); /* purecov: deadcode */ goto end_unlock;
close_thread_tables(thd); /* purecov: deadcode */
delete thd; /* purecov: deadcode */
DBUG_RETURN(1); /* purecov: deadcode */
} }
error = t_table->file->index_next(t_table->record[0]);
} }
my_pthread_setspecific_ptr(THR_MALLOC,old_root); while (!t_table->file->index_next(t_table->record[0]));
return_val=0; // Return ok
end_unlock:
mysql_unlock_tables(thd, lock); mysql_unlock_tables(thd, lock);
thd->version--; // Force close to free memory thd->version--; // Force close to free memory
end:
close_thread_tables(thd); close_thread_tables(thd);
delete thd; delete thd;
DBUG_RETURN(0); if (org_thd)
org_thd->store_globals();
DBUG_RETURN(return_val);
} }
...@@ -2720,7 +2723,8 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) ...@@ -2720,7 +2723,8 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
VOID(pthread_mutex_lock(&acl_cache->lock)); VOID(pthread_mutex_lock(&acl_cache->lock));
/* Add first global access grants */ /* Add first global access grants */
if (acl_user->access || acl_user->password) if (acl_user->access || acl_user->password ||
acl_user->ssl_type != SSL_TYPE_NONE)
{ {
want_access=acl_user->access; want_access=acl_user->access;
String global(buff,sizeof(buff)); String global(buff,sizeof(buff));
...@@ -2759,7 +2763,6 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) ...@@ -2759,7 +2763,6 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append(passd_buff); global.append(passd_buff);
global.append('\''); global.append('\'');
} }
#ifdef HAVE_OPENSSL
/* "show grants" SSL related stuff */ /* "show grants" SSL related stuff */
if (acl_user->ssl_type == SSL_TYPE_ANY) if (acl_user->ssl_type == SSL_TYPE_ANY)
global.append(" REQUIRE SSL",12); global.append(" REQUIRE SSL",12);
...@@ -2772,28 +2775,27 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) ...@@ -2772,28 +2775,27 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (acl_user->x509_issuer) if (acl_user->x509_issuer)
{ {
ssl_options++; ssl_options++;
global.append("ISSUER \"",8); global.append("ISSUER \'",8);
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
global.append('\''); global.append('\'');
} }
if (acl_user->x509_subject) if (acl_user->x509_subject)
{ {
if (ssl_options++) if (ssl_options++)
global.append(" AND ",5); global.append(' ');
global.append("SUBJECT \"",9); global.append("SUBJECT \'",9);
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
global.append('\''); global.append('\'');
} }
if (acl_user->ssl_cipher) if (acl_user->ssl_cipher)
{ {
if (ssl_options++) if (ssl_options++)
global.append(" AND ",5); global.append(' ');
global.append("CIPHER '",8); global.append("CIPHER '",8);
global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher)); global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
global.append('\''); global.append('\'');
} }
} }
#endif /* HAVE_OPENSSL */
if ((want_access & GRANT_ACL) || if ((want_access & GRANT_ACL) ||
(acl_user->user_resource.questions | acl_user->user_resource.updates | (acl_user->user_resource.questions | acl_user->user_resource.updates |
acl_user->user_resource.connections)) acl_user->user_resource.connections))
......
...@@ -70,8 +70,8 @@ ...@@ -70,8 +70,8 @@
/* prototypes */ /* prototypes */
int acl_init(bool dont_read_acl_tables); my_bool acl_init(bool dont_read_acl_tables);
void acl_reload(void); void acl_reload(THD *thd);
void acl_free(bool end=0); void acl_free(bool end=0);
ulong acl_get(const char *host, const char *ip, const char *bin_ip, ulong acl_get(const char *host, const char *ip, const char *bin_ip,
const char *user, const char *db); const char *user, const char *db);
...@@ -87,7 +87,7 @@ int mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list, ...@@ -87,7 +87,7 @@ int mysql_grant(THD *thd, const char *db, List <LEX_USER> &user_list,
int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list, int mysql_table_grant(THD *thd, TABLE_LIST *table, List <LEX_USER> &user_list,
List <LEX_COLUMN> &column_list, ulong rights, List <LEX_COLUMN> &column_list, ulong rights,
bool revoke); bool revoke);
int grant_init(void); my_bool grant_init(void);
void grant_free(void); void grant_free(void);
void grant_reload(void); void grant_reload(void);
bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
......
...@@ -1782,7 +1782,14 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields, ...@@ -1782,7 +1782,14 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
((Item_field*) item)->table_name,&it)) ((Item_field*) item)->table_name,&it))
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
if (sum_func_list) if (sum_func_list)
sum_func_list->elements += fields.elements - elem; {
/*
sum_func_list is a list that has the fields list as a tail.
Because of this we have to update the element count also for this
list after expanding the '*' entry.
*/
sum_func_list->elements+= fields.elements - elem;
}
} }
else else
{ {
......
...@@ -92,6 +92,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -92,6 +92,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
query_error=0; query_error=0;
next_insert_id=last_insert_id=0; next_insert_id=last_insert_id=0;
open_tables=temporary_tables=handler_tables=0; open_tables=temporary_tables=handler_tables=0;
current_tablenr=0;
handler_items=0; handler_items=0;
tmp_table=0; tmp_table=0;
lock=locked_tables=0; lock=locked_tables=0;
...@@ -136,6 +137,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -136,6 +137,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
command=COM_CONNECT; command=COM_CONNECT;
set_query_id=1; set_query_id=1;
db_access=NO_ACCESS; db_access=NO_ACCESS;
version=refresh_version; // For boot
/* Initialize sub structures */ /* Initialize sub structures */
bzero((char*) &mem_root,sizeof(mem_root)); bzero((char*) &mem_root,sizeof(mem_root));
...@@ -268,9 +270,13 @@ void THD::awake(bool prepare_to_die) ...@@ -268,9 +270,13 @@ void THD::awake(bool prepare_to_die)
bool THD::store_globals() bool THD::store_globals()
{ {
return (my_pthread_setspecific_ptr(THR_THD, this) || if (my_pthread_setspecific_ptr(THR_THD, this) ||
my_pthread_setspecific_ptr(THR_MALLOC, &mem_root) || my_pthread_setspecific_ptr(THR_MALLOC, &mem_root) ||
my_pthread_setspecific_ptr(THR_NET, &net)); my_pthread_setspecific_ptr(THR_NET, &net))
return 1;
mysys_var=my_thread_var;
dbug_thread_id=my_thread_id();
return 0;
} }
......
...@@ -475,6 +475,7 @@ class THD :public ilink { ...@@ -475,6 +475,7 @@ class THD :public ilink {
active_vio = 0; active_vio = 0;
pthread_mutex_unlock(&LOCK_delete); pthread_mutex_unlock(&LOCK_delete);
} }
void THD::close_active_vio();
#endif #endif
void awake(bool prepare_to_die); void awake(bool prepare_to_die);
inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex,
......
...@@ -941,8 +941,6 @@ static pthread_handler_decl(handle_delayed_insert,arg) ...@@ -941,8 +941,6 @@ static pthread_handler_decl(handle_delayed_insert,arg)
strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES)); strmov(thd->net.last_error,ER(thd->net.last_errno=ER_OUT_OF_RESOURCES));
goto end; goto end;
} }
thd->mysys_var=my_thread_var;
thd->dbug_thread_id=my_thread_id();
#if !defined(__WIN__) && !defined(OS2) #if !defined(__WIN__) && !defined(OS2)
sigset_t set; sigset_t set;
VOID(sigemptyset(&set)); // Get mask in use VOID(sigemptyset(&set)); // Get mask in use
......
...@@ -180,15 +180,14 @@ static int find_keyword(LEX *lex, uint len, bool function) ...@@ -180,15 +180,14 @@ static int find_keyword(LEX *lex, uint len, bool function)
udf_func *udf; udf_func *udf;
if (function && using_udf_functions && (udf=find_udf((char*) tok, len))) if (function && using_udf_functions && (udf=find_udf((char*) tok, len)))
{ {
lex->thd->safe_to_cache_query=0;
lex->yylval->udf=udf;
switch (udf->returns) { switch (udf->returns) {
case STRING_RESULT: case STRING_RESULT:
lex->yylval->udf=udf;
return (udf->type == UDFTYPE_FUNCTION) ? UDF_CHAR_FUNC : UDA_CHAR_SUM; return (udf->type == UDFTYPE_FUNCTION) ? UDF_CHAR_FUNC : UDA_CHAR_SUM;
case REAL_RESULT: case REAL_RESULT:
lex->yylval->udf=udf;
return (udf->type == UDFTYPE_FUNCTION) ? UDF_FLOAT_FUNC : UDA_FLOAT_SUM; return (udf->type == UDFTYPE_FUNCTION) ? UDF_FLOAT_FUNC : UDA_FLOAT_SUM;
case INT_RESULT: case INT_RESULT:
lex->yylval->udf=udf;
return (udf->type == UDFTYPE_FUNCTION) ? UDF_INT_FUNC : UDA_INT_SUM; return (udf->type == UDFTYPE_FUNCTION) ? UDF_INT_FUNC : UDA_INT_SUM;
} }
} }
......
...@@ -136,7 +136,7 @@ typedef struct st_lex ...@@ -136,7 +136,7 @@ typedef struct st_lex
char *backup_dir; /* For RESTORE/BACKUP */ char *backup_dir; /* For RESTORE/BACKUP */
char* to_log; /* For PURGE MASTER LOGS TO */ char* to_log; /* For PURGE MASTER LOGS TO */
char* x509_subject,*x509_issuer,*ssl_cipher; char* x509_subject,*x509_issuer,*ssl_cipher;
enum SSL_type ssl_type; /* defined in violite.h */ enum SSL_type ssl_type; /* defined in violite.h */
String *wild; String *wild;
sql_exchange *exchange; sql_exchange *exchange;
......
...@@ -621,9 +621,6 @@ pthread_handler_decl(handle_one_connection,arg) ...@@ -621,9 +621,6 @@ pthread_handler_decl(handle_one_connection,arg)
{ {
int error; int error;
NET *net= &thd->net; NET *net= &thd->net;
thd->mysys_var=my_thread_var;
thd->dbug_thread_id=my_thread_id();
thd->thread_stack= (char*) &thd; thd->thread_stack= (char*) &thd;
if ((error=check_connections(thd))) if ((error=check_connections(thd)))
...@@ -706,8 +703,6 @@ pthread_handler_decl(handle_bootstrap,arg) ...@@ -706,8 +703,6 @@ pthread_handler_decl(handle_bootstrap,arg)
pthread_detach_this_thread(); pthread_detach_this_thread();
thd->thread_stack= (char*) &thd; thd->thread_stack= (char*) &thd;
thd->mysys_var=my_thread_var;
thd->dbug_thread_id=my_thread_id();
#if !defined(__WIN__) && !defined(OS2) #if !defined(__WIN__) && !defined(OS2)
sigset_t set; sigset_t set;
VOID(sigemptyset(&set)); // Get mask in use VOID(sigemptyset(&set)); // Get mask in use
...@@ -3324,7 +3319,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) ...@@ -3324,7 +3319,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
select_errors=0; /* Write if more errors */ select_errors=0; /* Write if more errors */
if (options & REFRESH_GRANT) if (options & REFRESH_GRANT)
{ {
acl_reload(); acl_reload(thd);
grant_reload(); grant_reload();
if (mqh_used) if (mqh_used)
reset_mqh(thd,(LEX_USER *) NULL,true); reset_mqh(thd,(LEX_USER *) NULL,true);
......
...@@ -12,8 +12,7 @@ typedef struct st_slave_info ...@@ -12,8 +12,7 @@ typedef struct st_slave_info
} SLAVE_INFO; } SLAVE_INFO;
extern my_bool opt_show_slave_auth_info, opt_old_rpl_compat; extern my_bool opt_show_slave_auth_info, opt_old_rpl_compat;
extern char* master_host; extern char *master_host, *master_info_file;
extern my_string opt_bin_logname, master_info_file;
extern bool server_id_supplied; extern bool server_id_supplied;
extern I_List<i_string> binlog_do_db, binlog_ignore_db; extern I_List<i_string> binlog_do_db, binlog_ignore_db;
......
...@@ -132,13 +132,11 @@ void udf_init() ...@@ -132,13 +132,11 @@ void udf_init()
sql_print_error("Can't allocate memory for udf structures"); sql_print_error("Can't allocate memory for udf structures");
hash_free(&udf_hash); hash_free(&udf_hash);
free_root(&mem,MYF(0)); free_root(&mem,MYF(0));
delete new_thd;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
initialized = 1; initialized = 1;
new_thd->mysys_var=my_thread_var; new_thd->store_globals();
new_thd->version = refresh_version; //current_thd->version;
new_thd->current_tablenr = 0;
new_thd->open_tables = 0;
new_thd->db= my_strdup("mysql", MYF(0)); new_thd->db= my_strdup("mysql", MYF(0));
new_thd->db_length=5; new_thd->db_length=5;
...@@ -180,9 +178,10 @@ void udf_init() ...@@ -180,9 +178,10 @@ void udf_init()
{ {
if (!(dl = dlopen(tmp->dl, RTLD_NOW))) if (!(dl = dlopen(tmp->dl, RTLD_NOW)))
{ {
/* Print warning to log */
sql_print_error(ER(ER_CANT_OPEN_LIBRARY), sql_print_error(ER(ER_CANT_OPEN_LIBRARY),
tmp->dl,errno,dlerror()); tmp->dl,errno,dlerror());
del_udf(tmp); /* Keep the udf in the hash so that we can remove it later */
continue; continue;
} }
new_dl=1; new_dl=1;
...@@ -214,16 +213,17 @@ void udf_free() ...@@ -214,16 +213,17 @@ void udf_free()
for (uint idx=0 ; idx < udf_hash.records ; idx++) for (uint idx=0 ; idx < udf_hash.records ; idx++)
{ {
udf_func *udf=(udf_func*) hash_element(&udf_hash,idx); udf_func *udf=(udf_func*) hash_element(&udf_hash,idx);
if (udf->dl) if (udf->dlhandle) // Not closed before
{ {
/* Mark all versions using the same handler as closed */
for (uint j=idx+1 ; j < udf_hash.records ; j++) for (uint j=idx+1 ; j < udf_hash.records ; j++)
{ {
udf_func *tmp=(udf_func*) hash_element(&udf_hash,j); udf_func *tmp=(udf_func*) hash_element(&udf_hash,j);
if (tmp->dl && !strcmp(udf->dl,tmp->dl)) if (udf->dlhandle == tmp->dlhandle)
tmp->dl=0; tmp->dlhandle=0; // Already closed
} }
dlclose(udf->dlhandle);
} }
dlclose(udf->dlhandle);
} }
hash_free(&udf_hash); hash_free(&udf_hash);
free_root(&mem,MYF(0)); free_root(&mem,MYF(0));
...@@ -242,9 +242,9 @@ static void del_udf(udf_func *udf) ...@@ -242,9 +242,9 @@ static void del_udf(udf_func *udf)
else else
{ {
/* /*
** The functions is in use ; Rename the functions instead of removing it. The functions is in use ; Rename the functions instead of removing it.
** The functions will be automaticly removed when the least threads The functions will be automaticly removed when the least threads
** doesn't use it anymore doesn't use it anymore
*/ */
char *name= udf->name; char *name= udf->name;
uint name_length=udf->name_length; uint name_length=udf->name_length;
...@@ -262,6 +262,10 @@ void free_udf(udf_func *udf) ...@@ -262,6 +262,10 @@ void free_udf(udf_func *udf)
pthread_mutex_lock(&THR_LOCK_udf); pthread_mutex_lock(&THR_LOCK_udf);
if (!--udf->usage_count) if (!--udf->usage_count)
{ {
/*
We come here when someone has deleted the udf function
while another thread still was using the udf
*/
hash_delete(&udf_hash,(byte*) udf); hash_delete(&udf_hash,(byte*) udf);
using_udf_functions=udf_hash.records != 0; using_udf_functions=udf_hash.records != 0;
if (!find_udf_dl(udf->dl)) if (!find_udf_dl(udf->dl))
...@@ -271,6 +275,7 @@ void free_udf(udf_func *udf) ...@@ -271,6 +275,7 @@ void free_udf(udf_func *udf)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* This is only called if using_udf_functions != 0 */ /* This is only called if using_udf_functions != 0 */
udf_func *find_udf(const char *name,uint length,bool mark_used) udf_func *find_udf(const char *name,uint length,bool mark_used)
...@@ -282,18 +287,22 @@ udf_func *find_udf(const char *name,uint length,bool mark_used) ...@@ -282,18 +287,22 @@ udf_func *find_udf(const char *name,uint length,bool mark_used)
pthread_mutex_lock(&THR_LOCK_udf); pthread_mutex_lock(&THR_LOCK_udf);
udf=(udf_func*) hash_search(&udf_hash,(byte*) name, udf=(udf_func*) hash_search(&udf_hash,(byte*) name,
length ? length : (uint) strlen(name)); length ? length : (uint) strlen(name));
if (mark_used) if (!udf->dlhandle)
udf=0; // Could not be opened
else if (mark_used)
udf->usage_count++; udf->usage_count++;
pthread_mutex_unlock(&THR_LOCK_udf); pthread_mutex_unlock(&THR_LOCK_udf);
DBUG_RETURN(udf); DBUG_RETURN(udf);
} }
static void *find_udf_dl(const char *dl) static void *find_udf_dl(const char *dl)
{ {
DBUG_ENTER("find_udf_dl"); DBUG_ENTER("find_udf_dl");
/* because only the function name is hashed, we have to search trough /*
** all rows to find the dl. Because only the function name is hashed, we have to search trough
all rows to find the dl.
*/ */
for (uint idx=0 ; idx < udf_hash.records ; idx++) for (uint idx=0 ; idx < udf_hash.records ; idx++)
{ {
...@@ -310,7 +319,7 @@ static void *find_udf_dl(const char *dl) ...@@ -310,7 +319,7 @@ static void *find_udf_dl(const char *dl)
static udf_func *add_udf(char *name, Item_result ret, char *dl, static udf_func *add_udf(char *name, Item_result ret, char *dl,
Item_udftype type) Item_udftype type)
{ {
if (!name || !dl) if (!name || !dl || !(uint) type || (uint) type > (uint) UDFTYPE_AGGREGATE)
return 0; return 0;
udf_func *tmp= (udf_func*) alloc_root(&mem, sizeof(udf_func)); udf_func *tmp= (udf_func*) alloc_root(&mem, sizeof(udf_func));
if (!tmp) if (!tmp)
...@@ -362,7 +371,7 @@ int mysql_create_function(THD *thd,udf_func *udf) ...@@ -362,7 +371,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
} }
pthread_mutex_lock(&THR_LOCK_udf); pthread_mutex_lock(&THR_LOCK_udf);
if (hash_search(&udf_hash,(byte*) udf->name, udf->name_length)) if ((hash_search(&udf_hash,(byte*) udf->name, udf->name_length)))
{ {
net_printf(&thd->net, ER_UDF_EXISTS, udf->name); net_printf(&thd->net, ER_UDF_EXISTS, udf->name);
goto err; goto err;
...@@ -388,8 +397,7 @@ int mysql_create_function(THD *thd,udf_func *udf) ...@@ -388,8 +397,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
} }
udf->name=strdup_root(&mem,udf->name); udf->name=strdup_root(&mem,udf->name);
udf->dl=strdup_root(&mem,udf->dl); udf->dl=strdup_root(&mem,udf->dl);
if (!udf->name || !udf->dl || if (!(u_d=add_udf(udf->name,udf->returns,udf->dl,udf->type)))
!(u_d=add_udf(udf->name,udf->returns,udf->dl,udf->type)))
{ {
send_error(&thd->net,0); // End of memory send_error(&thd->net,0); // End of memory
goto err; goto err;
...@@ -448,13 +456,18 @@ int mysql_drop_function(THD *thd,const char *udf_name) ...@@ -448,13 +456,18 @@ int mysql_drop_function(THD *thd,const char *udf_name)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
pthread_mutex_lock(&THR_LOCK_udf); pthread_mutex_lock(&THR_LOCK_udf);
if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name, (uint) strlen(udf_name)))) if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name,
(uint) strlen(udf_name))))
{ {
net_printf(&thd->net, ER_FUNCTION_NOT_DEFINED, udf_name); net_printf(&thd->net, ER_FUNCTION_NOT_DEFINED, udf_name);
goto err; goto err;
} }
del_udf(udf); del_udf(udf);
if (!find_udf_dl(udf->dl)) /*
Close the handle if this was function that was found during boot or
CREATE FUNCTION and it's not in use by any other udf function
*/
if (udf->dlhandle && !find_udf_dl(udf->dl))
dlclose(udf->dlhandle); dlclose(udf->dlhandle);
bzero((char*) &tables,sizeof(tables)); bzero((char*) &tables,sizeof(tables));
...@@ -480,10 +493,3 @@ int mysql_drop_function(THD *thd,const char *udf_name) ...@@ -480,10 +493,3 @@ int mysql_drop_function(THD *thd,const char *udf_name)
} }
#endif /* HAVE_DLOPEN */ #endif /* HAVE_DLOPEN */
/*
** Local variables:
** tab-width: 8
** c-basic-offset: 2
** End:
*/
...@@ -126,6 +126,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -126,6 +126,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MASTER_SYM %token MASTER_SYM
%token MAX_SYM %token MAX_SYM
%token MIN_SYM %token MIN_SYM
%token NONE_SYM
%token OPTIMIZE %token OPTIMIZE
%token PURGE %token PURGE
%token REPAIR %token REPAIR
...@@ -589,7 +590,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -589,7 +590,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
table_to_table_list table_to_table opt_table_list opt_as table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild union union_list single_multi table_wild_list table_wild_one opt_wild union union_list
precision union_option precision union_option opt_and
END_OF_INPUT END_OF_INPUT
%type <NONE> %type <NONE>
...@@ -1856,7 +1857,6 @@ simple_expr: ...@@ -1856,7 +1857,6 @@ simple_expr:
$$ = new Item_sum_udf_str($1, *$3); $$ = new Item_sum_udf_str($1, *$3);
else else
$$ = new Item_sum_udf_str($1); $$ = new Item_sum_udf_str($1);
current_thd->safe_to_cache_query=0;
} }
| UDA_FLOAT_SUM '(' udf_expr_list ')' | UDA_FLOAT_SUM '(' udf_expr_list ')'
{ {
...@@ -1864,7 +1864,6 @@ simple_expr: ...@@ -1864,7 +1864,6 @@ simple_expr:
$$ = new Item_sum_udf_float($1, *$3); $$ = new Item_sum_udf_float($1, *$3);
else else
$$ = new Item_sum_udf_float($1); $$ = new Item_sum_udf_float($1);
current_thd->safe_to_cache_query=0;
} }
| UDA_INT_SUM '(' udf_expr_list ')' | UDA_INT_SUM '(' udf_expr_list ')'
{ {
...@@ -1879,7 +1878,6 @@ simple_expr: ...@@ -1879,7 +1878,6 @@ simple_expr:
$$ = new Item_func_udf_str($1, *$3); $$ = new Item_func_udf_str($1, *$3);
else else
$$ = new Item_func_udf_str($1); $$ = new Item_func_udf_str($1);
current_thd->safe_to_cache_query=0;
} }
| UDF_FLOAT_FUNC '(' udf_expr_list ')' | UDF_FLOAT_FUNC '(' udf_expr_list ')'
{ {
...@@ -1887,7 +1885,6 @@ simple_expr: ...@@ -1887,7 +1885,6 @@ simple_expr:
$$ = new Item_func_udf_float($1, *$3); $$ = new Item_func_udf_float($1, *$3);
else else
$$ = new Item_func_udf_float($1); $$ = new Item_func_udf_float($1);
current_thd->safe_to_cache_query=0;
} }
| UDF_INT_FUNC '(' udf_expr_list ')' | UDF_INT_FUNC '(' udf_expr_list ')'
{ {
...@@ -1895,7 +1892,6 @@ simple_expr: ...@@ -1895,7 +1892,6 @@ simple_expr:
$$ = new Item_func_udf_int($1, *$3); $$ = new Item_func_udf_int($1, *$3);
else else
$$ = new Item_func_udf_int($1); $$ = new Item_func_udf_int($1);
current_thd->safe_to_cache_query=0;
} }
| UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')' | UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
{ {
...@@ -3168,6 +3164,7 @@ keyword: ...@@ -3168,6 +3164,7 @@ keyword:
| NEXT_SYM {} | NEXT_SYM {}
| NEW_SYM {} | NEW_SYM {}
| NO_SYM {} | NO_SYM {}
| NONE_SYM {}
| OPEN_SYM {} | OPEN_SYM {}
| PACK_KEYS_SYM {} | PACK_KEYS_SYM {}
| PASSWORD {} | PASSWORD {}
...@@ -3458,13 +3455,13 @@ grant: ...@@ -3458,13 +3455,13 @@ grant:
GRANT GRANT
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command = SQLCOM_GRANT;
lex->users_list.empty(); lex->users_list.empty();
lex->columns.empty(); lex->columns.empty();
lex->grant= lex->grant_tot_col=0; lex->sql_command = SQLCOM_GRANT;
lex->select->db=0; lex->grant= lex->grant_tot_col= 0;
lex->ssl_type=SSL_TYPE_NONE; lex->select->db= 0;
lex->ssl_cipher=lex->x509_subject=lex->x509_issuer=0; lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
bzero(&(lex->mqh),sizeof(lex->mqh)); bzero(&(lex->mqh),sizeof(lex->mqh));
} }
grant_privileges ON opt_table TO_SYM user_list grant_privileges ON opt_table TO_SYM user_list
...@@ -3504,10 +3501,19 @@ grant_privilege: ...@@ -3504,10 +3501,19 @@ grant_privilege:
| REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL;} | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL;}
; ;
require_list: require_list_element AND require_list
| require_list_element ;
require_list_element: SUBJECT_SYM TEXT_STRING opt_and:
/* empty */ {}
| AND {}
;
require_list:
require_list_element opt_and require_list
| require_list_element
;
require_list_element:
SUBJECT_SYM TEXT_STRING
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->x509_subject) if (lex->x509_subject)
...@@ -3651,17 +3657,21 @@ column_list_id: ...@@ -3651,17 +3657,21 @@ column_list_id:
require_clause: /* empty */ require_clause: /* empty */
| REQUIRE_SYM require_list | REQUIRE_SYM require_list
{ {
Lex->ssl_type=SSL_TYPE_SPECIFIED; Lex->ssl_type=SSL_TYPE_SPECIFIED;
} }
| REQUIRE_SYM SSL_SYM | REQUIRE_SYM SSL_SYM
{ {
Lex->ssl_type=SSL_TYPE_ANY; Lex->ssl_type=SSL_TYPE_ANY;
} }
| REQUIRE_SYM X509_SYM | REQUIRE_SYM X509_SYM
{ {
Lex->ssl_type=SSL_TYPE_X509; Lex->ssl_type=SSL_TYPE_X509;
}; }
| REQUIRE_SYM NONE_SYM
{
Lex->ssl_type=SSL_TYPE_NONE;
}
grant_options: grant_options:
/* empty */ {} /* empty */ {}
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
** On the end is a couple of functions that converts hostnames to ip and ** On the end is a couple of functions that converts hostnames to ip and
** vice versa. ** vice versa.
** **
** A dynamicly loadable file should be compiled sharable ** A dynamicly loadable file should be compiled shared.
** (something like: gcc -shared -o my_func.so myfunc.cc). ** (something like: gcc -shared -o my_func.so myfunc.cc).
** You can easily get all switches right by doing: ** You can easily get all switches right by doing:
** cd sql ; make udf_example.o ** cd sql ; make udf_example.o
...@@ -69,6 +69,8 @@ ...@@ -69,6 +69,8 @@
** the line and add -shared -o udf_example.so to the end of the compile line. ** the line and add -shared -o udf_example.so to the end of the compile line.
** The resulting library (udf_example.so) should be copied to some dir ** The resulting library (udf_example.so) should be copied to some dir
** searched by ld. (/usr/lib ?) ** searched by ld. (/usr/lib ?)
** If you are using gcc, then you should be able to create the udf_example.so
** by simply doing 'make udf_example.so'.
** **
** After the library is made one must notify mysqld about the new ** After the library is made one must notify mysqld about the new
** functions with the commands: ** functions with the commands:
......
/******************************************************************************
* *
* N O T I C E *
* *
* Copyright Abandoned, 1987, Fred Fish *
* *
* *
* This previously copyrighted work has been placed into the public *
* domain by the author and may be freely used for any purpose, *
* private or commercial. *
* *
* Because of the number of inquiries I was receiving about the use *
* of this product in commercially developed works I have decided to *
* simply make it public domain to further its unrestricted use. I *
* specifically would be most happy to see this material become a *
* part of the standard Unix distributions by AT&T and the Berkeley *
* Computer Science Research Group, and a standard part of the GNU *
* system from the Free Software Foundation. *
* *
* I would appreciate it, as a courtesy, if this notice is left in *
* all copies and derivative works. Thank you. *
* *
* The author makes no warranty of any kind with respect to this *
* product and explicitly disclaims any implied warranties of mer- *
* chantability or fitness for any particular purpose. *
* *
******************************************************************************
*/
The *MySQL* server license for non Microsoft operating systems
**************************************************************
*MySQL FREE PUBLIC LICENSE*
(Version 4, March 5, 1995)
Copyright (C) 1995, 1996 TcX AB & Monty Program KB & Detron HB
Stockholm SWEDEN, Helsingfors FINLAND and Uppsala SWEDEN
All rights reserved.
NOTE: This license is not the same as any of the GNU Licenses published
by the Free Software Foundation. Its terms are substantially different
from those of the GNU Licenses. If you are familiar with the GNU
Licenses, please read this license with extra care.
This License applies to the computer program known as "MySQL". The
"Program", below, refers to such program, and a "work based on the
Program" means either the Program or any derivative work of the Program,
as defined in the United States Copyright Act of 1976, such as a
translation or a modification. The Program is a copyrighted work whose
copyright is held by TcX Datakonsult AB and Monty Program KB and Detron
HB.
This License does not apply when running "MySQL" on any Microsoft
operating system. Microsoft operating systems include all versions of
Microsoft Windows NT and Microsoft Windows.
BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE
PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL
ITS TERMS AND CONDITIONS FOR COPYING, DISTRIBUTING OR MODIFYING THE
PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS
YOU PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE
WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE
TERMS AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM.
1. Licenses.
Licensor hereby grants you the following rights, provided that you
comply with all of the restrictions set forth in this License and
provided, further, that you distribute an unmodified copy of this
License with the Program:
a. You may copy and distribute literal (i.e., verbatim) copies
of the Program's source code as you receive it throughout the
world, in any medium.
b. You may modify the Program, create works based on the Program
and distribute copies of such throughout the world, in any
medium.
2. Restrictions.
This license is subject to the following restrictions:
a. Distribution of the Program or any work based on the Program
by a commercial organization to any third party is prohibited
if any payment is made in connection with such distribution,
whether directly (as in payment for a copy of the Program) or
indirectly (as in payment for some service related to the
Program, or payment for some product or service that includes
a copy of the Program "without charge"; these are only
examples, and not an exhaustive enumeration of prohibited
activities). However, the following methods of distribution
involving payment shall not in and of themselves be a
violation of this restriction:
A. Posting the Program on a public access information
storage and retrieval service for which a fee is
received for retrieving information (such as an on-line
service), provided that the fee is not content-dependent
(i.e., the fee would be the same for retrieving the same
volume of information consisting of random data).
B. Distributing the Program on a CD-ROM, provided that the
files containing the Program are reproduced entirely and
verbatim on such CD-ROM, and provided further that all
information on such CD-ROM be redistributable for
non-commercial purposes without charge.
b. Activities other than copying, distribution and modification
of the Program are not subject to this License and they are
outside its scope. Functional use (running) of the Program
is not restricted, and any output produced through the use of
the Program is subject to this license only if its contents
constitute a work based on the Program (independent of having
been made by running the Program).
c. You must meet all of the following conditions with respect to
the distribution of any work based on the Program:
A. If you have modified the Program, you must cause your
work to carry prominent notices stating that you have
modified the Program's files and the date of any change;
B. You must cause any work that you distribute or publish,
that in whole or in part contains or is derived from the
Program or any part thereof, to be licensed as a whole
and at no charge to all third parties under the terms of
this License;
C. If the modified program normally reads commands
interactively when run, you must cause it, at each time
the modified program commences operation, to print or
display an announcement including an appropriate
copyright notice and a notice that there is no warranty
(or else, saying that you provide a warranty). Such
notice must also state that users may redistribute the
Program only under the conditions of this License and
tell the user how to view the copy of this License
included with the Program. (Exception: if the Program
itself is interactive but does not normally print such
an announcement, your work based on the Program is not
required to print an announcement.);
D. You must accompany any such work based on the Program
with the complete corresponding machine-readable source
code, delivered on a medium customarily used for
software interchange. The source code for a work means
the preferred form of the work for making modifications
to it. For an executable work, complete source code
means all the source code for all modules it contains,
plus any associated interface definition files, plus the
scripts used to control compilation and installation of
the executable code. However, the source code
distributed need not include anything that is normally
distributed (in either source or binary form) with the
major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless
that component itself accompanies the executable code;
E. If you distribute any written or printed material at all
with the Program or any work based on the Program, such
material must include either a written copy of this
License, or a prominent written indication that the
Program or the work based on the Program is covered by
this License and written instructions for printing
and/or displaying the copy of the License on the
distribution medium;
F. You may not impose any further restrictions on the
recipient's exercise of the rights granted herein.
If distribution of executable or object code is made by
offering the equivalent ability to copy from a
designated place, then offering equivalent ability to
copy the source code from the same place counts as
distribution of the source code, even though third
parties are not compelled to copy the source code along
with the object code.
3. Reservation of Rights.
No rights are granted to the Program except as expressly set forth
herein. You may not copy, modify, sublicense, or distribute the
Program except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense or distribute the
Program is void, and will automatically terminate your rights
under this License. However, parties who have received copies, or
rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
4. Other Restrictions.
If the distribution and/or use of the Program is restricted in
certain countries for any reason, Licensor may add an explicit
geographical distribution limitation excluding those countries, so
that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation
as if written in the body of this License.
5. Limitations.
THE PROGRAM IS PROVIDED TO YOU "AS IS," WITHOUT WARRANTY. THERE IS
NO WARRANTY FOR THE PROGRAM, EITHER EXPRESSED OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE
QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
SERVICING, REPAIR OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL LICENSOR, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
THE POSSIBILITY OF SUCH DAMAGES.
Roughly the same as "Linux Kernel Coding Style", which is
included in file LinuxKernelCodingStyle.
Some methods are meant to be used as set/get, for example, there
are:
virtual bool Vio::blocking();
virtual int Vio::blocking(bool block);
Virtual IO library.
IO wrappers for sockets, fd-s, SSL.
Languages:C++
This library is based on work of many others.
They have different policies and I haven't thought up
about resulting licence - GPL, L(essen)GPL, BSD-style, whatever.
The licences are here for reference:
COPYING.mysql: MySQL licence. Some socket functions.
COPYING.dbug: Fred Fish's dbug library. I use it extensively ;=)
COPYING.openssl:OpenSSL licence. SSL wrappers.
At the moment there is no real 'Makefile', just config.mk/targets.mk
and Makefile.am to build it as a module in MySQL. Therefore, there
is currently no possibility to build it as a separate library, but
with MySQL-s root Makefile it should just a matter of leaving
everything else out.
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