Below is the list of changes that have just been committed into a local
5.0 repository of guilhem. When guilhem does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1974 05/11/14 23:06:17 guilhem@stripped +27 -0
Merge mysql.com:/home/mysql_src/mysql-5.0
into mysql.com:/home/mysql_src/mysql-5.0-wl1012
(some bad merges will be fixed manually right now)
sql/sql_parse.cc
1.475 05/11/14 23:06:12 guilhem@stripped +6 -5
merge
sql/sql_class.h
1.270 05/11/14 23:06:12 guilhem@stripped +8 -0
merge
sql/share/errmsg.txt
1.55 05/11/14 23:06:12 guilhem@stripped +2 -6
merge
sql/mysqld.cc
1.489 05/11/14 23:06:12 guilhem@stripped +2 -5
merge
sql/log.cc
1.187 05/11/14 23:06:12 guilhem@stripped +6 -35
merge
sql/item_func.cc
1.260 05/11/14 23:06:12 guilhem@stripped +0 -0
merge
mysql-test/t/rpl_stm_sp.test
1.11 05/11/14 23:06:12 guilhem@stripped +7 -48
merge
mysql-test/r/rpl_stm_sp.result
1.12 05/11/14 23:06:12 guilhem@stripped +2 -103
merge
sql/table.h
1.113 05/11/14 17:01:01 guilhem@stripped +0 -0
Auto merged
sql/sql_table.cc
1.279 05/11/14 17:01:01 guilhem@stripped +0 -0
Auto merged
sql/sql_show.cc
1.268 05/11/14 17:01:01 guilhem@stripped +0 -0
Auto merged
sql/sql_select.cc
1.354 05/11/14 17:01:00 guilhem@stripped +0 -0
Auto merged
sql/sql_prepare.cc
1.163 05/11/14 17:01:00 guilhem@stripped +0 -0
Auto merged
sql/sql_acl.cc
1.175 05/11/14 17:01:00 guilhem@stripped +0 -0
Auto merged
sql/sp_head.cc
1.195 05/11/14 17:01:00 guilhem@stripped +0 -0
Auto merged
sql/sp.cc
1.96 05/11/14 17:01:00 guilhem@stripped +0 -0
Auto merged
sql/set_var.cc
1.138 05/11/14 17:00:59 guilhem@stripped +0 -0
Auto merged
sql/mysql_priv.h
1.350 05/11/14 17:00:59 guilhem@stripped +0 -0
Auto merged
sql/handler.h
1.158 05/11/14 17:00:59 guilhem@stripped +0 -0
Auto merged
sql/ha_innodb.cc
1.250 05/11/14 17:00:59 guilhem@stripped +0 -0
Auto merged
mysql-test/t/rpl_trigger.test
1.5 05/11/14 17:00:59 guilhem@stripped +0 -0
Auto merged
mysql-test/t/rpl_stm_sp-slave.opt
1.3 05/11/14 17:00:59 guilhem@stripped +0 -0
Auto merged
mysql-test/r/rpl_stm_ddl.result
1.11 05/11/14 17:00:59 guilhem@stripped +0 -0
Auto merged
mysql-test/mysql-test-run.sh
1.280 05/11/14 17:00:59 guilhem@stripped +0 -0
Auto merged
mysql-test/t/rpl_stm_sp.test
1.4.4.2 05/11/14 17:00:58 guilhem@stripped +0 -0
Merge rename: mysql-test/t/rpl_sp.test -> mysql-test/t/rpl_stm_sp.test
mysql-test/t/rpl_stm_sp-slave.opt
1.1.1.2 05/11/14 17:00:58 guilhem@stripped +0 -0
Merge rename: mysql-test/t/rpl_sp-slave.opt -> mysql-test/t/rpl_stm_sp-slave.opt
mysql-test/r/rpl_stm_sp.result
1.5.4.4 05/11/14 17:00:58 guilhem@stripped +0 -0
Merge rename: mysql-test/r/rpl_sp.result -> mysql-test/r/rpl_stm_sp.result
mysql-test/r/rpl_stm_ddl.result
1.6.3.2 05/11/14 17:00:58 guilhem@stripped +0 -0
Merge rename: mysql-test/r/rpl_ddl.result -> mysql-test/r/rpl_stm_ddl.result
mysql-test/mysql-test-run.pl
1.44 05/11/14 17:00:58 guilhem@stripped +0 -0
Auto merged
include/my_global.h
1.104 05/11/14 17:00:58 guilhem@stripped +0 -0
Auto merged
configure.in
1.350 05/11/14 17:00:58 guilhem@stripped +0 -0
Auto merged
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: guilhem
# Host: gbichot3.local
# Root: /home/mysql_src/mysql-5.0-wl1012/RESYNC
--- 1.349/configure.in 2005-11-04 10:43:44 +01:00
+++ 1.350/configure.in 2005-11-14 17:00:58 +01:00
@@ -7,7 +7,7 @@
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.0.16)
+AM_INIT_AUTOMAKE(mysql, 5.0.17)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
@@ -18,7 +18,7 @@
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
-NDB_VERSION_BUILD=16
+NDB_VERSION_BUILD=17
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
@@ -335,6 +335,10 @@
# Use the built-in alloca()
CFLAGS="$CFLAGS -Kalloca"
CXXFLAGS="$CFLAGS -Kalloca"
+ # Use no_implicit for templates
+ CXXFLAGS="$CXXFLAGS -Tno_implicit"
+ AC_DEFINE([HAVE_EXPLICIT_TEMPLATE_INSTANTIATION],
+ [1], [Defined by configure. Use explicit template instantiation.])
fi
;;
esac
--- 1.279/mysql-test/mysql-test-run.sh 2005-11-04 10:43:44 +01:00
+++ 1.280/mysql-test/mysql-test-run.sh 2005-11-14 17:00:59 +01:00
@@ -1278,7 +1278,7 @@
--language=$LANGUAGE \
--innodb_data_file_path=ibdata1:128M:autoextend \
--open-files-limit=1024 \
- --log-bin-trust-routine-creators \
+ --log-bin-trust-function-creators \
$MASTER_40_ARGS \
$SMALL_SERVER \
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
@@ -1299,7 +1299,7 @@
--tmpdir=$MYSQL_TMP_DIR \
--language=$LANGUAGE \
--innodb_data_file_path=ibdata1:128M:autoextend \
- --log-bin-trust-routine-creators \
+ --log-bin-trust-function-creators \
$MASTER_40_ARGS \
$SMALL_SERVER \
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
@@ -1432,7 +1432,7 @@
--report-port=$slave_port \
--master-retry-count=10 \
-O slave_net_timeout=10 \
- --log-bin-trust-routine-creators \
+ --log-bin-trust-function-creators \
$SMALL_SERVER \
$EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT"
CUR_MYERR=$slave_err
--- 1.157/sql/handler.h 2005-11-04 10:43:45 +01:00
+++ 1.158/sql/handler.h 2005-11-14 17:00:59 +01:00
@@ -45,6 +45,7 @@
#define HA_ADMIN_REJECT -6
#define HA_ADMIN_TRY_ALTER -7
#define HA_ADMIN_WRONG_CHECKSUM -8
+#define HA_ADMIN_NOT_BASE_TABLE -9
/* Bits in table_flags() to show what database can do */
@@ -407,8 +408,9 @@
/* Possible flags of a handlerton */
#define HTON_NO_FLAGS 0
#define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
-#define HTON_ALTER_NOT_SUPPORTED (1 << 1)
-#define HTON_CAN_RECREATE (1 << 2)
+#define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
+#define HTON_CAN_RECREATE (1 << 2) //Delete all is used fro truncate
+#define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
typedef struct st_thd_trans
{
--- 1.259/sql/item_func.cc 2005-11-04 10:43:45 +01:00
+++ 1.260/sql/item_func.cc 2005-11-14 23:06:12 +01:00
@@ -4775,12 +4775,6 @@
res= m_sp->execute_function(thd, args, arg_count, itp);
thd->restore_sub_statement_state(&statement_state);
- if (res && !binlog_row_based && mysql_bin_log.is_open() &&
- (m_sp->m_chistics->daccess == SP_CONTAINS_SQL ||
- m_sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_FAILED_ROUTINE_BREAK_BINLOG,
- ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
sp_restore_security_context(thd, save_ctx_func);
error:
@@ -4894,7 +4888,7 @@
/*
- Find the function and chack access rigths to the function
+ Find the function and check access rights to the function
SYNOPSIS
find_and_check_access()
--- 1.186/sql/log.cc 2005-11-04 10:43:45 +01:00
+++ 1.187/sql/log.cc 2005-11-14 23:06:12 +01:00
@@ -67,7 +67,7 @@
NULL, /* create_cursor_read_view */
NULL, /* set_cursor_read_view */
NULL, /* close_cursor_read_view */
- HTON_NO_FLAGS
+ HTON_HIDDEN
};
/*
@@ -356,12 +356,11 @@
MYSQL_LOG::MYSQL_LOG()
- :reset_pending(false), readers_count(0),
- bytes_written(0), last_time(0), query_start(0), name(0),
- file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0),
- need_start_event(1), prepared_xids(0),
- m_next_table_id(0), m_table_map_version(0),
- description_event_for_exec(0), description_event_for_queue(0)
+ :bytes_written(0), last_time(0), query_start(0), name(0),
+ prepared_xids(0), log_type(LOG_CLOSED), file_id(1), open_count(1),
+ write_error(FALSE), inited(FALSE), need_start_event(TRUE),
+ description_event_for_exec(0), description_event_for_queue(0),
+ m_next_table_id(0), m_table_version(0)
{
/*
We don't want to initialize LOCK_Log here as such initialization depends on
@@ -387,10 +386,8 @@
delete description_event_for_exec;
(void) pthread_mutex_destroy(&LOCK_log);
(void) pthread_mutex_destroy(&LOCK_index);
- (void) pthread_mutex_destroy(&LOCK_readers);
(void) pthread_cond_destroy(&update_cond);
(void) pthread_mutex_destroy(&LOCK_next_table_id);
- (void) pthread_cond_destroy(&reset_cond);
}
DBUG_VOID_RETURN;
}
@@ -435,10 +432,8 @@
inited= 1;
(void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
- (void) pthread_mutex_init(&LOCK_readers, MY_MUTEX_INIT_SLOW);
(void) pthread_cond_init(&update_cond, 0);
(void) pthread_mutex_init(&LOCK_next_table_id, MY_MUTEX_INIT_FAST);
- (void) pthread_cond_init(&reset_cond, 0);
}
const char *MYSQL_LOG::generate_name(const char *log_name,
@@ -942,12 +937,6 @@
pthread_mutex_lock(&LOCK_log);
pthread_mutex_lock(&LOCK_index);
- /*
- we need one more lock to block attempts to open a log while
- we are waiting untill all log files will be closed
- */
- pthread_mutex_lock(&LOCK_readers);
-
/*
The following mutex is needed to ensure that no threads call
'delete thd' as we would then risk missing a 'rollback' from this
@@ -970,19 +959,6 @@
goto err;
}
- reset_pending= TRUE;
- /*
- send update signal just in case so that all reader threads waiting
- for log update will leave wait condition
- */
- signal_update();
- /*
- if there are active readers wait until all of them will
- release opened files
- */
- while (readers_count)
- pthread_cond_wait(&reset_cond, &LOCK_log);
-
for (;;)
{
my_delete(linfo.log_file_name, MYF(MY_WME));
@@ -1001,10 +977,7 @@
my_free((gptr) save_name, MYF(0));
err:
- reset_pending= FALSE;
-
(void) pthread_mutex_unlock(&LOCK_thread_count);
- pthread_mutex_unlock(&LOCK_readers);
pthread_mutex_unlock(&LOCK_index);
pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
@@ -2081,12 +2054,6 @@
{
const char *old_msg;
DBUG_ENTER("wait_for_update");
-
- if (reset_pending)
- {
- pthread_mutex_unlock(&LOCK_log);
- DBUG_VOID_RETURN;
- }
old_msg= thd->enter_cond(&update_cond, &LOCK_log,
is_slave ?
@@ -2380,35 +2347,8 @@
/* BUG this is an incrementation without LOCK_log mutex */
m_table_map_version++;
}
-
#endif /* !defined(MYSQL_CLIENT) */
-void MYSQL_LOG::readers_addref()
-{
- /*
- There is no necessity for reference counting on *nix, since it allows to
- delete opened files, however it is more clean way to wait
- untill all files will be closed on *nix as well.
- */
- DBUG_ENTER("MYSQL_LOG::reader_addref");
- pthread_mutex_lock(&LOCK_log);
- pthread_mutex_lock(&LOCK_readers);
- readers_count++;
- pthread_mutex_unlock(&LOCK_readers);
- pthread_mutex_unlock(&LOCK_log);
- DBUG_VOID_RETURN;
-}
-
-void MYSQL_LOG::readers_release()
-{
- DBUG_ENTER("MYSQL_LOG::reader_release");
- pthread_mutex_lock(&LOCK_log);
- readers_count--;
- if (!readers_count)
- pthread_cond_broadcast(&reset_cond);
- pthread_mutex_unlock(&LOCK_log);
- DBUG_VOID_RETURN;
-}
#ifdef __NT__
void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
--- 1.349/sql/mysql_priv.h 2005-11-04 10:43:45 +01:00
+++ 1.350/sql/mysql_priv.h 2005-11-14 17:00:59 +01:00
@@ -44,6 +44,12 @@
typedef ulonglong table_map; /* Used for table bits in join */
typedef Bitmap<64> key_map; /* Used for finding keys */
typedef ulong key_part_map; /* Used for finding key parts */
+/*
+ Used to identify NESTED_JOIN structures within a join (applicable only to
+ structures that have not been simplified away and embed more the one
+ element)
+*/
+typedef ulonglong nested_join_map;
/* query_id */
typedef ulonglong query_id_t;
@@ -516,8 +522,9 @@
bool insert_precheck(THD *thd, TABLE_LIST *tables);
bool create_table_precheck(THD *thd, TABLE_LIST *tables,
TABLE_LIST *create_table);
-bool default_view_definer(Security_context *sctx, st_lex_user *definer);
+bool get_default_definer(THD *thd, LEX_USER *definer);
+LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
@@ -841,6 +848,10 @@
bool mysqld_help (THD *thd, const char *text);
void calc_sum_of_all_status(STATUS_VAR *to);
+void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
+ const LEX_STRING *definer_host);
+
+
/* information schema */
extern LEX_STRING information_schema_name;
LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
@@ -1181,7 +1192,7 @@
extern my_bool opt_secure_auth;
extern my_bool opt_log_slow_admin_statements;
extern my_bool sp_automatic_privileges, opt_noacl;
-extern my_bool opt_old_style_user_limits, trust_routine_creators;
+extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb;
extern char *shared_memory_base_name, *mysqld_unix_port;
extern my_bool opt_enable_shared_memory;
--- 1.488/sql/mysqld.cc 2005-11-04 10:43:45 +01:00
+++ 1.489/sql/mysqld.cc 2005-11-14 23:06:12 +01:00
@@ -371,7 +371,7 @@
my_bool lower_case_file_system= 0;
my_bool opt_large_pages= 0;
uint opt_large_page_size= 0;
-my_bool opt_old_style_user_limits= 0, trust_routine_creators= 0;
+my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
/*
True if there is at least one per-hour limit for some user, so we should
check them before each query (and possibly reset counters when hour is
@@ -592,7 +592,7 @@
static const char* default_dbug_option;
#endif
#ifdef HAVE_LIBWRAP
-char *libwrapName= NULL;
+const char *libwrapName= NULL;
#endif
#ifdef HAVE_QUERY_CACHE
static ulong query_cache_limit= 0;
@@ -1222,6 +1222,7 @@
(void) rwlock_destroy(&LOCK_sys_init_slave);
(void) pthread_mutex_destroy(&LOCK_global_system_variables);
(void) pthread_mutex_destroy(&LOCK_global_read_lock);
+ (void) pthread_mutex_destroy(&LOCK_uuid_generator);
(void) pthread_cond_destroy(&COND_thread_count);
(void) pthread_cond_destroy(&COND_refresh);
(void) pthread_cond_destroy(&COND_thread_cache);
@@ -4499,7 +4500,7 @@
OPT_INNODB_FAST_SHUTDOWN,
OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB,
OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
- OPT_LOG_BIN_TRUST_ROUTINE_CREATORS,
+ OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG,
OPT_INNODB, OPT_ISAM,
OPT_ENGINE_CONDITION_PUSHDOWN,
@@ -4952,20 +4953,31 @@
"File that holds the names for last binary log files.",
(gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef TO_BE_REMOVED_IN_5_1_OR_6_0
+ /*
+ In 5.0.6 we introduced the below option, then in 5.0.16 we renamed it to
+ log-bin-trust-function-creators but kept also the old name for
+ compatibility; the behaviour was also changed to apply only to functions
+ (and triggers). In a future release this old name could be removed.
+ */
+ {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
+ "(deprecated) Use log-bin-trust-function-creators.",
+ (gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+#endif
/*
This option starts with "log-bin" to emphasize that it is specific of
- binary logging. Hopefully in 5.1 nobody will need it anymore, when we have
- row-level binlog.
+ binary logging.
*/
- {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_ROUTINE_CREATORS,
+ {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
"If equal to 0 (the default), then when --log-bin is used, creation of "
- "a routine is allowed only to users having the SUPER privilege (because of "
- "security issues) and only if this routine may not break binary logging."
+ "a function is allowed only to users having the SUPER privilege and only "
+ "if this function may not break binary logging."
#ifdef HAVE_ROW_BASED_REPLICATION
" If using --binlog-format=row, the security issues do not exist and the "
"binary logging cannot break so this option is automatically set to 1."
#endif
- ,(gptr*) &trust_routine_creators, (gptr*) &trust_routine_creators, 0,
+ ,(gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
(gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR,
@@ -5824,7 +5836,7 @@
(gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
{"read_only", OPT_READONLY,
- "Make all tables readonly, with the exception for replication (slave) threads and users with the SUPER privilege",
+ "Make all non-temporary tables read-only, with the exception for replication (slave) threads and users with the SUPER privilege",
(gptr*) &opt_readonly,
(gptr*) &opt_readonly,
0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
--- 1.174/sql/sql_acl.cc 2005-11-04 10:43:45 +01:00
+++ 1.175/sql/sql_acl.cc 2005-11-14 17:01:00 +01:00
@@ -3532,7 +3532,7 @@
of other queries). For simple queries first_not_own_table is 0.
*/
for (i= 0, table= tables;
- table != first_not_own_table && i < number;
+ table && table != first_not_own_table && i < number;
table= table->next_global, i++)
{
/* Remove SHOW_VIEW_ACL, because it will be checked during making view */
--- 1.269/sql/sql_class.h 2005-11-03 23:28:58 +01:00
+++ 1.270/sql/sql_class.h 2005-11-14 23:06:12 +01:00
@@ -192,11 +192,10 @@
{
private:
/* LOCK_log and LOCK_index are inited by init_pthread_objects() */
- pthread_mutex_t LOCK_log, LOCK_index, LOCK_readers;
+ pthread_mutex_t LOCK_log, LOCK_index;
+ pthread_mutex_t LOCK_prep_xids;
+ pthread_cond_t COND_prep_xids;
pthread_cond_t update_cond;
- pthread_cond_t reset_cond;
- bool reset_pending;
- int readers_count;
ulonglong bytes_written;
time_t last_time,query_start;
IO_CACHE log_file;
@@ -204,21 +203,6 @@
char *name;
char time_buff[20],db[NAME_LEN+1];
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
- // current file sequence number for load data infile binary logging
- uint file_id;
- uint open_count; // For replication
- volatile enum_log_type log_type;
- enum cache_type io_cache_type;
- bool write_error, inited;
- bool need_start_event;
- /*
- no_auto_events means we don't want any of these automatic events :
- Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't want
- a Rotate_log event to be written to the relay log. When we start a relay log
- etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
- In 5.0 it's 0 for relay logs too!
- */
- bool no_auto_events;
/*
The max size before rotation (usable only if log_type == LOG_BIN: binary
logs and relay logs).
@@ -230,10 +214,24 @@
fix_max_relay_log_size).
*/
ulong max_size;
-
ulong prepared_xids; /* for tc log - number of xids to remember */
- pthread_mutex_t LOCK_prep_xids;
- pthread_cond_t COND_prep_xids;
+ volatile enum_log_type log_type;
+ enum cache_type io_cache_type;
+ // current file sequence number for load data infile binary logging
+ uint file_id;
+ uint open_count; // For replication
+ int readers_count;
+ bool reset_pending;
+ bool write_error, inited;
+ bool need_start_event;
+ /*
+ no_auto_events means we don't want any of these automatic events :
+ Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't
+ want a Rotate_log event to be written to the relay log. When we start a
+ relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
+ In 5.0 it's 0 for relay logs too!
+ */
+ bool no_auto_events;
friend class Log_event;
pthread_mutex_t LOCK_next_table_id;
@@ -242,6 +240,17 @@
ulonglong m_table_map_version;
public:
+ /*
+ These describe the log's format. This is used only for relay logs.
+ _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
+ necessary to have 2 distinct objects, because the I/O thread may be reading
+ events in a different format from what the SQL thread is reading (consider
+ the case of a master which has been upgraded from 5.0 to 5.1 without doing
+ RESET MASTER, or from 4.x to 5.0).
+ */
+ Format_description_log_event *description_event_for_exec,
+ *description_event_for_queue;
+
MYSQL_LOG();
/*
note that there's no destructor ~MYSQL_LOG() !
@@ -254,7 +263,6 @@
int log(THD *thd, my_xid xid);
void unlog(ulong cookie, my_xid xid);
int recover(IO_CACHE *log, Format_description_log_event *fdle);
-
#if !defined(MYSQL_CLIENT)
/*
This will return a table id for the table. If the table is not known, a
@@ -263,17 +271,6 @@
ulong get_table_id(TABLE* table);
void update_table_map_version();
#endif /* !defined(MYSQL_CLIENT) */
- /*
- These describe the log's format. This is used only for relay logs.
- _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
- necessary to have 2 distinct objects, because the I/O thread may be reading
- events in a different format from what the SQL thread is reading (consider
- the case of a master which has been upgraded from 5.0 to 5.1 without doing
- RESET MASTER, or from 4.x to 5.0).
- */
- Format_description_log_event *description_event_for_exec,
- *description_event_for_queue;
-
void reset_bytes_written()
{
bytes_written = 0;
@@ -353,9 +350,6 @@
int purge_logs_before_date(time_t purge_time);
int purge_first_log(struct st_relay_log_info* rli, bool included);
bool reset_logs(THD* thd);
- inline bool is_reset_pending() { return reset_pending; }
- void readers_addref();
- void readers_release();
void close(uint exiting);
// iterating through the log index file
--- 1.474/sql/sql_parse.cc 2005-11-04 10:43:45 +01:00
+++ 1.475/sql/sql_parse.cc 2005-11-14 23:06:12 +01:00
@@ -194,6 +194,18 @@
#endif
+static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
+{
+ for (TABLE_LIST *table= tables; table; table= table->next_global)
+ {
+ DBUG_ASSERT(table->db && table->table_name);
+ if (table->updating &&
+ !find_temporary_table(thd, table->db, table->table_name))
+ return 1;
+ }
+ return 0;
+}
+
static HASH hash_user_connections;
static int get_or_create_user_conn(THD *thd, const char *user,
@@ -2365,7 +2377,7 @@
mysql_reset_errors(thd, 0);
#ifdef HAVE_REPLICATION
- if (thd->slave_thread)
+ if (unlikely(thd->slave_thread))
{
/*
Check if statment should be skipped because of slave filtering
@@ -2404,16 +2416,20 @@
}
#endif
}
+ else
#endif /* HAVE_REPLICATION */
/*
- When option readonly is set deny operations which change tables.
- Except for the replication thread and the 'super' users.
+ When option readonly is set deny operations which change non-temporary
+ tables. Except for the replication thread and the 'super' users.
*/
if (opt_readonly &&
- !(thd->slave_thread ||
- (thd->security_ctx->master_access & SUPER_ACL)) &&
- uc_update_queries[lex->sql_command])
+ !(thd->security_ctx->master_access & SUPER_ACL) &&
+ uc_update_queries[lex->sql_command] &&
+ !((lex->sql_command == SQLCOM_CREATE_TABLE) &&
+ (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
+ ((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
+ some_non_temp_table_to_be_updated(thd, all_tables)))
{
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
DBUG_RETURN(-1);
@@ -3211,14 +3227,22 @@
break;
#ifdef HAVE_REPLICATION
- /* Check slave filtering rules */
- if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
+ if (unlikely(thd->slave_thread))
+ if (all_tables_not_ok(thd, all_tables))
{
- /* we warn the slave SQL thread */
- my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
- break;
+ /* we warn the slave SQL thread */
+ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
+ break;
}
+ else
#endif /* HAVE_REPLICATION */
+ if (opt_readonly &&
+ !(thd->security_ctx->master_access & SUPER_ACL) &&
+ some_non_temp_table_to_be_updated(thd, all_tables))
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
+ break;
+ }
res= mysql_multi_update(thd, all_tables,
&select_lex->item_list,
@@ -4072,7 +4096,7 @@
if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0])
{
- if (! thd->db)
+ if (!thd->db)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
delete lex->sphead;
@@ -4291,17 +4315,6 @@
So just execute the statement.
*/
res= sp->execute_procedure(thd, &lex->value_list);
- if (!binlog_row_based && mysql_bin_log.is_open() &&
- (sp->m_chistics->daccess == SP_CONTAINS_SQL ||
- sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
- {
- if (res)
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_FAILED_ROUTINE_BREAK_BINLOG,
- ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
- else
- thd->clear_error();
- }
/*
If warnings have been cleared, we have to clear total_warn_count
too, otherwise the clients get confused.
@@ -4360,7 +4373,8 @@
if (end_active_trans(thd))
goto error;
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
- if (!trust_routine_creators && mysql_bin_log.is_open() &&
+ if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
+ !trust_function_creators && mysql_bin_log.is_open() &&
!sp->m_chistics->detistic &&
(chistics.daccess == SP_CONTAINS_SQL ||
chistics.daccess == SP_MODIFIES_SQL_DATA))
@@ -4371,6 +4385,12 @@
}
else
{
+ /*
+ Note that if you implement the capability of ALTER FUNCTION to
+ alter the body of the function, this command should be made to
+ follow the restrictions that log-bin-trust-function-creators=0
+ already puts on CREATE FUNCTION.
+ */
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
else
@@ -5034,7 +5054,7 @@
the given table list refers to the list for prelocking (contains tables
of other queries). For simple queries first_not_own_table is 0.
*/
- for (; tables != first_not_own_table; tables= tables->next_global)
+ for (; tables && tables != first_not_own_table; tables= tables->next_global)
{
if (tables->schema_table &&
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
@@ -7438,32 +7458,81 @@
return new Item_func_not(expr);
}
+/*
+ Set the specified definer to the default value, which is the current user in
+ the thread. Also check that the current user satisfies to the definers
+ requirements.
+
+ SYNOPSIS
+ get_default_definer()
+ thd [in] thread handler
+ definer [out] definer
+
+ RETURN
+ error status, that is:
+ - FALSE -- on success;
+ - TRUE -- on error (current user can not be a definer).
+*/
+
+bool get_default_definer(THD *thd, LEX_USER *definer)
+{
+ /* Check that current user has non-empty host name. */
+
+ const Security_context *sctx= thd->security_ctx;
+
+ if (sctx->priv_host[0] == 0)
+ {
+ my_error(ER_MALFORMED_DEFINER, MYF(0));
+ return TRUE;
+ }
+
+ /* Fill in. */
+
+ definer->user.str= (char *) sctx->priv_user;
+ definer->user.length= strlen(definer->user.str);
+
+ definer->host.str= (char *) sctx->priv_host;
+ definer->host.length= strlen(definer->host.str);
+
+ return FALSE;
+}
+
/*
- Assign as view definer current user
+ Create definer with the given user and host names. Also check that the user
+ and host names satisfy definers requirements.
SYNOPSIS
- default_view_definer()
- sctx current security context
- definer structure where it should be assigned
+ create_definer()
+ thd [in] thread handler
+ user_name [in] user name
+ host_name [in] host name
RETURN
- FALSE OK
- TRUE Error
+ On success, return a valid pointer to the created and initialized
+ LEX_STRING, which contains definer information.
+ On error, return 0.
*/
-bool default_view_definer(Security_context *sctx, st_lex_user *definer)
+LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
{
- definer->user.str= sctx->priv_user;
- definer->user.length= strlen(sctx->priv_user);
+ LEX_USER *definer;
- if (!*sctx->priv_host)
+ /* Check that specified host name is valid. */
+
+ if (host_name->length == 0)
{
- my_error(ER_NO_VIEW_USER, MYF(0));
- return TRUE;
+ my_error(ER_MALFORMED_DEFINER, MYF(0));
+ return 0;
}
- definer->host.str= sctx->priv_host;
- definer->host.length= strlen(sctx->priv_host);
- return FALSE;
+ /* Create and initialize. */
+
+ if (! (definer= (LEX_USER*) thd->alloc(sizeof (LEX_USER))))
+ return 0;
+
+ definer->user= *user_name;
+ definer->host= *host_name;
+
+ return definer;
}
--- 1.353/sql/sql_select.cc 2005-11-04 10:43:46 +01:00
+++ 1.354/sql/sql_select.cc 2005-11-14 17:01:00 +01:00
@@ -98,6 +98,12 @@
void *table_join_idx);
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
COND *conds, bool top);
+static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next);
+static void restore_prev_nj_state(JOIN_TAB *last);
+static void reset_nj_counters(List<TABLE_LIST> *join_list);
+static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
+ uint first_unused);
+
static COND *optimize_cond(JOIN *join, COND *conds,
List<TABLE_LIST> *join_list,
Item::cond_result *cond_value);
@@ -520,12 +526,14 @@
return 0;
}
+
/*
global select optimisation.
return 0 - success
1 - error
error code saved in field 'error'
*/
+
int
JOIN::optimize()
{
@@ -588,6 +596,7 @@
/* Convert all outer joins to inner joins if possible */
conds= simplify_joins(this, join_list, conds, TRUE);
+ build_bitmap_for_nested_joins(join_list, 0);
sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
@@ -700,7 +709,8 @@
DBUG_PRINT("error",("Error: make_select() failed"));
DBUG_RETURN(1);
}
-
+
+ reset_nj_counters(join_list);
make_outerjoin_info(this);
/*
@@ -1968,14 +1978,19 @@
continue;
}
outer_join|= table->map;
+ s->embedding_map= 0;
+ for (;embedding; embedding= embedding->embedding)
+ s->embedding_map|= embedding->nested_join->nj_map;
continue;
}
if (embedding)
{
/* s belongs to a nested join, maybe to several embedded joins */
+ s->embedding_map= 0;
do
{
NESTED_JOIN *nested_join= embedding->nested_join;
+ s->embedding_map|=nested_join->nj_map;
s->dependent|= embedding->dep_tables;
embedding= embedding->embedding;
outer_join|= nested_join->used_tables;
@@ -3549,6 +3564,8 @@
bool straight_join= join->select_options & SELECT_STRAIGHT_JOIN;
DBUG_ENTER("choose_plan");
+ join->cur_embedding_map= 0;
+ reset_nj_counters(join->join_list);
/*
if (SELECT_STRAIGHT_JOIN option is set)
reorder tables so dependent tables come after tables they depend
@@ -4029,7 +4046,9 @@
for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
{
table_map real_table_bit= s->table->map;
- if ((remaining_tables & real_table_bit) && !(remaining_tables & s->dependent))
+ if ((remaining_tables & real_table_bit) &&
+ !(remaining_tables & s->dependent) &&
+ (!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s)))
{
double current_record_count, current_read_time;
@@ -4045,6 +4064,7 @@
{
DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
"prune_by_cost"););
+ restore_prev_nj_state(s);
continue;
}
@@ -4073,6 +4093,7 @@
{
DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
"pruned_by_heuristic"););
+ restore_prev_nj_state(s);
continue;
}
}
@@ -4107,9 +4128,11 @@
sizeof(POSITION) * (idx + 1));
join->best_read= current_read_time - 0.001;
}
- DBUG_EXECUTE("opt",
- print_plan(join, current_read_time, current_record_count, idx, "full_plan"););
+ DBUG_EXECUTE("opt", print_plan(join, current_read_time,
+ current_record_count, idx,
+ "full_plan"););
}
+ restore_prev_nj_state(s);
}
}
DBUG_VOID_RETURN;
@@ -4154,7 +4177,8 @@
for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++)
{
table_map real_table_bit=s->table->map;
- if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent))
+ if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
+ (!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
{
double best,best_time,records;
best=best_time=records=DBL_MAX;
@@ -4492,10 +4516,10 @@
join->unit->select_limit_cnt >= records)
join->sort_by_table= (TABLE*) 1; // Must use temporary table
- /*
+ /*
Go to the next level only if there hasn't been a better key on
this level! This will cut down the search for a lot simple cases!
- */
+ */
double current_record_count=record_count*records;
double current_read_time=read_time+best;
if (best_record_count > current_record_count ||
@@ -4516,6 +4540,7 @@
return;
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
}
+ restore_prev_nj_state(s);
if (join->select_options & SELECT_STRAIGHT_JOIN)
break; // Don't test all combinations
}
@@ -5101,7 +5126,7 @@
This function can be called only after the execution plan
has been chosen.
*/
-
+
static void
make_outerjoin_info(JOIN *join)
{
@@ -7262,11 +7287,11 @@
ascent all attributes are calculated, all outer joins that can be
converted are replaced and then all unnecessary braces are removed.
As join list contains join tables in the reverse order sequential
- elimination of outer joins does not requite extra recursive calls.
+ elimination of outer joins does not require extra recursive calls.
EXAMPLES
Here is an example of a join query with invalid cross references:
- SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN ON t3.b=t1.b
+ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN t3 ON t3.b=t1.b
RETURN VALUE
The new condition, if success
@@ -7423,7 +7448,257 @@
}
DBUG_RETURN(conds);
}
-
+
+
+/*
+ Assign each nested join structure a bit in nested_join_map
+
+ SYNOPSIS
+ build_bitmap_for_nested_joins()
+ join Join being processed
+ join_list List of tables
+ first_unused Number of first unused bit in nested_join_map before the
+ call
+
+ DESCRIPTION
+ Assign each nested join structure (except "confluent" ones - those that
+ embed only one element) a bit in nested_join_map.
+
+ NOTE
+ This function is called after simplify_joins(), when there are no
+ redundant nested joins, #non_confluent_nested_joins <= #tables_in_join so
+ we will not run out of bits in nested_join_map.
+
+ RETURN
+ First unused bit in nested_join_map after the call.
+*/
+
+static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
+ uint first_unused)
+{
+ List_iterator<TABLE_LIST> li(*join_list);
+ TABLE_LIST *table;
+ DBUG_ENTER("build_bitmap_for_nested_joins");
+ while ((table= li++))
+ {
+ NESTED_JOIN *nested_join;
+ if ((nested_join= table->nested_join))
+ {
+ /*
+ It is guaranteed by simplify_joins() function that a nested join
+ that has only one child represents a single table VIEW (and the child
+ is an underlying table). We don't assign bits to such nested join
+ structures because
+ 1. it is redundant (a "sequence" of one table cannot be interleaved
+ with anything)
+ 2. we could run out bits in nested_join_map otherwise.
+ */
+ if (nested_join->join_list.elements != 1)
+ {
+ nested_join->nj_map= 1 << first_unused++;
+ first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
+ first_unused);
+ }
+ }
+ }
+ DBUG_RETURN(first_unused);
+}
+
+
+/*
+ Set NESTED_JOIN::counter=0 in all nested joins in passed list
+
+ SYNOPSIS
+ reset_nj_counters()
+ join_list List of nested joins to process. It may also contain base
+ tables which will be ignored.
+
+ DESCRIPTION
+ Recursively set NESTED_JOIN::counter=0 for all nested joins contained in
+ the passed join_list.
+*/
+
+static void reset_nj_counters(List<TABLE_LIST> *join_list)
+{
+ List_iterator<TABLE_LIST> li(*join_list);
+ TABLE_LIST *table;
+ DBUG_ENTER("reset_nj_counters");
+ while ((table= li++))
+ {
+ NESTED_JOIN *nested_join;
+ if ((nested_join= table->nested_join))
+ {
+ nested_join->counter= 0;
+ reset_nj_counters(&nested_join->join_list);
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Check interleaving with an inner tables of an outer join for extension table
+
+ SYNOPSIS
+ check_interleaving_with_nj()
+ join Join being processed
+ last_tab Last table in current partial join order (this function is
+ not called for empty partial join orders)
+ next_tab Table we're going to extend the current partial join with
+
+ DESCRIPTION
+ Check if table next_tab can be added to current partial join order, and
+ if yes, record that it has been added.
+
+ The function assumes that both current partial join order and its
+ extension with next_tab are valid wrt table dependencies.
+
+ IMPLEMENTATION
+ LIMITATIONS ON JOIN ORDER
+ The nested [outer] joins executioner algorithm imposes these limitations
+ on join order:
+ 1. "Outer tables first" - any "outer" table must be before any
+ corresponding "inner" table.
+ 2. "No interleaving" - tables inside a nested join must form a continuous
+ sequence in join order (i.e. the sequence must not be interrupted by
+ tables that are outside of this nested join).
+
+ #1 is checked elsewhere, this function checks #2 provided that #1 has
+ been already checked.
+
+ WHY NEED NON-INTERLEAVING
+ Consider an example:
+
+ select * from t0 join t1 left join (t2 join t3) on cond1
+
+ The join order "t1 t2 t0 t3" is invalid:
+
+ table t0 is outside of the nested join, so WHERE condition for t0 is
+ attached directly to t0 (without triggers, and it may be used to access
+ t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss
+ combinations of (t1, t2, t3) that satisfy condition cond1, and produce a
+ null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have
+ been produced.
+
+ If table t0 is not between t2 and t3, the problem doesn't exist:
+ * If t0 is located after (t2,t3), WHERE(t0) is applied after nested join
+ processing has finished.
+ * If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are
+ wrapped into condition triggers, which takes care of correct nested
+ join processing.
+
+ HOW IT IS IMPLEMENTED
+ The limitations on join order can be rephrased as follows: for valid
+ join order one must be able to:
+ 1. write down the used tables in the join order on one line.
+ 2. for each nested join, put one '(' and one ')' on the said line
+ 3. write "LEFT JOIN" and "ON (...)" where appropriate
+ 4. get a query equivalent to the query we're trying to execute.
+
+ Calls to check_interleaving_with_nj() are equivalent to writing the
+ above described line from left to right.
+ A single check_interleaving_with_nj(A,B) call is equivalent to writing
+ table B and appropriate brackets on condition that table A and
+ appropriate brackets is the last what was written. Graphically the
+ transition is as follows:
+
+ +---- current position
+ |
+ ... last_tab ))) | ( next_tab ) )..) | ...
+ X Y Z |
+ +- need to move to this
+ position.
+
+ Notes about the position:
+ The caller guarantees that there is no more then one X-bracket by
+ checking "!(remaining_tables & s->dependent)" before calling this
+ function. X-bracket may have a pair in Y-bracket.
+
+ When "writing" we store/update this auxilary info about the current
+ position:
+ 1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
+ joins) we've opened but didn't close.
+ 2. {each NESTED_JOIN structure not simplified away}->counter - number
+ of this nested join's children that have already been added to to
+ the partial join order.
+
+ RETURN
+ FALSE Join order extended, nested joins info about current join order
+ (see NOTE section) updated.
+ TRUE Requested join order extension not allowed.
+*/
+
+static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab)
+{
+ TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding;
+ JOIN *join= last_tab->join;
+
+ if (join->cur_embedding_map & ~next_tab->embedding_map)
+ {
+ /*
+ next_tab is outside of the "pair of brackets" we're currently in.
+ Cannot add it.
+ */
+ return TRUE;
+ }
+
+ /*
+ Do update counters for "pairs of brackets" that we've left (marked as
+ X,Y,Z in the above picture)
+ */
+ for (;next_emb; next_emb= next_emb->embedding)
+ {
+ next_emb->nested_join->counter++;
+ if (next_emb->nested_join->counter == 1)
+ {
+ /*
+ next_emb is the first table inside a nested join we've "entered". In
+ the picture above, we're looking at the 'X' bracket. Don't exit yet as
+ X bracket might have Y pair bracket.
+ */
+ join->cur_embedding_map |= next_emb->nested_join->nj_map;
+ }
+
+ if (next_emb->nested_join->join_list.elements !=
+ next_emb->nested_join->counter)
+ break;
+
+ /*
+ We're currently at Y or Z-bracket as depicted in the above picture.
+ Mark that we've left it and continue walking up the brackets hierarchy.
+ */
+ join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
+ }
+ return FALSE;
+}
+
+
+/*
+ Nested joins perspective: Remove the last table from the join order
+
+ SYNOPSIS
+ restore_prev_nj_state()
+ last join table to remove, it is assumed to be the last in current
+ partial join order.
+
+ DESCRIPTION
+ Remove the last table from the partial join order and update the nested
+ joins counters and join->cur_embedding_map. It is ok to call this
+ function for the first table in join order (for which
+ check_interleaving_with_nj has not been called)
+*/
+
+static void restore_prev_nj_state(JOIN_TAB *last)
+{
+ TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding;
+ JOIN *join= last->join;
+ while (last_emb && !(--last_emb->nested_join->counter))
+ {
+ join->cur_embedding_map &= last_emb->nested_join->nj_map;
+ last_emb= last_emb->embedding;
+ }
+}
+
static COND *
optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
--- 1.267/sql/sql_show.cc 2005-11-04 10:43:46 +01:00
+++ 1.268/sql/sql_show.cc 2005-11-14 17:01:01 +01:00
@@ -70,17 +70,20 @@
handlerton **types;
for (types= sys_table_types; *types; types++)
{
- protocol->prepare_for_resend();
- protocol->store((*types)->name, system_charset_info);
- const char *option_name= show_comp_option_name[(int) (*types)->state];
-
- if ((*types)->state == SHOW_OPTION_YES &&
- !my_strcasecmp(system_charset_info, default_type_name, (*types)->name))
- option_name= "DEFAULT";
- protocol->store(option_name, system_charset_info);
- protocol->store((*types)->comment, system_charset_info);
- if (protocol->write())
- DBUG_RETURN(TRUE);
+ if (!((*types)->flags & HTON_HIDDEN))
+ {
+ protocol->prepare_for_resend();
+ protocol->store((*types)->name, system_charset_info);
+ const char *option_name= show_comp_option_name[(int) (*types)->state];
+
+ if ((*types)->state == SHOW_OPTION_YES &&
+ !my_strcasecmp(system_charset_info, default_type_name, (*types)->name))
+ option_name= "DEFAULT";
+ protocol->store(option_name, system_charset_info);
+ protocol->store((*types)->comment, system_charset_info);
+ if (protocol->write())
+ DBUG_RETURN(TRUE);
+ }
}
send_eof(thd);
DBUG_RETURN(FALSE);
@@ -359,7 +362,21 @@
/* Only one table for now, but VIEW can involve several tables */
if (open_normal_and_derived_tables(thd, table_list, 0))
- DBUG_RETURN(TRUE);
+ {
+ if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID)
+ DBUG_RETURN(TRUE);
+ /*
+ Clear all messages with 'error' level status and
+ issue a warning with 'warning' level status in
+ case of invalid view and last error is ER_VIEW_INVALID
+ */
+ mysql_reset_errors(thd, true);
+ push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_VIEW_INVALID,
+ ER(ER_VIEW_INVALID),
+ table_list->view_db.str,
+ table_list->view_name.str);
+ }
/* TODO: add environment variables show when it become possible */
if (thd->lex->only_view && !table_list->view)
@@ -1060,18 +1077,36 @@
default:
DBUG_ASSERT(0); // never should happen
}
- buff->append("DEFINER=", 8);
- append_identifier(thd, buff,
- table->definer.user.str, table->definer.user.length);
- buff->append('@');
- append_identifier(thd, buff,
- table->definer.host.str, table->definer.host.length);
+ append_definer(thd, buff, &table->definer.user, &table->definer.host);
if (table->view_suid)
- buff->append(" SQL SECURITY DEFINER ", 22);
+ buff->append("SQL SECURITY DEFINER ", 21);
else
- buff->append(" SQL SECURITY INVOKER ", 22);
+ buff->append("SQL SECURITY INVOKER ", 21);
}
+
+/*
+ Append DEFINER clause to the given buffer.
+
+ SYNOPSIS
+ append_definer()
+ thd [in] thread handle
+ buffer [inout] buffer to hold DEFINER clause
+ definer_user [in] user name part of definer
+ definer_host [in] host name part of definer
+*/
+
+void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
+ const LEX_STRING *definer_host)
+{
+ buffer->append(STRING_WITH_LEN("DEFINER="));
+ append_identifier(thd, buffer, definer_user->str, definer_user->length);
+ buffer->append('@');
+ append_identifier(thd, buffer, definer_host->str, definer_host->length);
+ buffer->append(' ');
+}
+
+
static int
view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
{
@@ -2971,47 +3006,44 @@
DBUG_ENTER("get_schema_views_record");
char definer[HOSTNAME_LENGTH + USERNAME_LENGTH + 2];
uint definer_len;
- if (!res)
- {
- if (tables->view)
- {
- restore_record(table, s->default_values);
- table->field[1]->store(tables->view_db.str, tables->view_db.length, cs);
- table->field[2]->store(tables->view_name.str, tables->view_name.length,
- cs);
- table->field[3]->store(tables->query.str, tables->query.length, cs);
- if (tables->with_check != VIEW_CHECK_NONE)
- {
- if (tables->with_check == VIEW_CHECK_LOCAL)
- table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs);
- else
- table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs);
- }
- else
- table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
+ if (tables->view)
+ {
+ restore_record(table, s->default_values);
+ table->field[1]->store(tables->view_db.str, tables->view_db.length, cs);
+ table->field[2]->store(tables->view_name.str, tables->view_name.length,
+ cs);
+ table->field[3]->store(tables->query.str, tables->query.length, cs);
- if (tables->updatable_view)
- table->field[5]->store(STRING_WITH_LEN("YES"), cs);
- else
- table->field[5]->store(STRING_WITH_LEN("NO"), cs);
- definer_len= (strxmov(definer, tables->definer.user.str, "@",
- tables->definer.host.str, NullS) - definer);
- table->field[6]->store(definer, definer_len, cs);
- if (tables->view_suid)
- table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
+ if (tables->with_check != VIEW_CHECK_NONE)
+ {
+ if (tables->with_check == VIEW_CHECK_LOCAL)
+ table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs);
else
- table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
- DBUG_RETURN(schema_table_store_record(thd, table));
+ table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs);
}
- }
- else
- {
- if (tables->view)
+ else
+ table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
+
+ if (tables->updatable_view)
+ table->field[5]->store(STRING_WITH_LEN("YES"), cs);
+ else
+ table->field[5]->store(STRING_WITH_LEN("NO"), cs);
+ definer_len= (strxmov(definer, tables->definer.user.str, "@",
+ tables->definer.host.str, NullS) - definer);
+ table->field[6]->store(definer, definer_len, cs);
+ if (tables->view_suid)
+ table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
+ else
+ table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
+ if (schema_table_store_record(thd, table))
+ DBUG_RETURN(1);
+ if (res)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
thd->net.last_errno, thd->net.last_error);
- thd->clear_error();
}
+ if (res)
+ thd->clear_error();
DBUG_RETURN(0);
}
@@ -3094,7 +3126,8 @@
enum trg_event_type event,
enum trg_action_time_type timing,
LEX_STRING *trigger_stmt,
- ulong sql_mode)
+ ulong sql_mode,
+ LEX_STRING *definer_buffer)
{
CHARSET_INFO *cs= system_charset_info;
byte *sql_mode_str;
@@ -3119,6 +3152,7 @@
sql_mode,
&sql_mode_len);
table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs);
+ table->field[18]->store((const char *)definer_buffer->str, definer_buffer->length, cs);
return schema_table_store_record(thd, table);
}
@@ -3152,15 +3186,21 @@
LEX_STRING trigger_name;
LEX_STRING trigger_stmt;
ulong sql_mode;
+ char definer_holder[HOSTNAME_LENGTH + USERNAME_LENGTH + 2];
+ LEX_STRING definer_buffer;
+ definer_buffer.str= definer_holder;
if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
(enum trg_action_time_type)timing,
&trigger_name, &trigger_stmt,
- &sql_mode))
+ &sql_mode,
+ &definer_buffer))
continue;
+
if (store_trigger(thd, table, base_name, file_name, &trigger_name,
(enum trg_event_type) event,
(enum trg_action_time_type) timing, &trigger_stmt,
- sql_mode))
+ sql_mode,
+ &definer_buffer))
DBUG_RETURN(1);
}
}
@@ -4064,6 +4104,7 @@
{"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
{"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"},
{"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"},
+ {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer"},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
};
--- 1.278/sql/sql_table.cc 2005-11-04 10:43:46 +01:00
+++ 1.279/sql/sql_table.cc 2005-11-14 17:01:01 +01:00
@@ -840,6 +840,7 @@
else
{
/* Field redefined */
+ sql_field->def= dup_field->def;
sql_field->sql_type= dup_field->sql_type;
sql_field->charset= (dup_field->charset ?
dup_field->charset :
@@ -849,8 +850,15 @@
sql_field->key_length= dup_field->key_length;
sql_field->create_length_to_internal_length();
sql_field->decimals= dup_field->decimals;
- sql_field->flags= dup_field->flags;
sql_field->unireg_check= dup_field->unireg_check;
+ /*
+ We're making one field from two, the result field will have
+ dup_field->flags as flags. If we've incremented null_fields
+ because of sql_field->flags, decrement it back.
+ */
+ if (!(sql_field->flags & NOT_NULL_FLAG))
+ null_fields--;
+ sql_field->flags= dup_field->flags;
it2.remove(); // Remove first (create) definition
select_field_pos--;
break;
@@ -2206,7 +2214,7 @@
/* if view are unsupported */
if (table->view && view_operator_func == NULL)
{
- result_code= HA_ADMIN_NOT_IMPLEMENTED;
+ result_code= HA_ADMIN_NOT_BASE_TABLE;
goto send_result;
}
thd->open_options&= ~extra_open_options;
@@ -2341,6 +2349,16 @@
}
break;
+ case HA_ADMIN_NOT_BASE_TABLE:
+ {
+ char buf[ERRMSGSIZE+20];
+ uint length= my_snprintf(buf, ERRMSGSIZE,
+ ER(ER_BAD_TABLE_ERROR), table_name);
+ protocol->store("note", 4, system_charset_info);
+ protocol->store(buf, length, system_charset_info);
+ }
+ break;
+
case HA_ADMIN_OK:
protocol->store("status", 6, system_charset_info);
protocol->store("OK",2, system_charset_info);
@@ -2441,16 +2459,19 @@
break;
}
}
- if (fatal_error)
- table->table->s->version=0; // Force close of table
- else if (open_for_modify)
+ if (table->table)
{
- pthread_mutex_lock(&LOCK_open);
- remove_table_from_cache(thd, table->table->s->db,
- table->table->s->table_name, RTFC_NO_FLAG);
- pthread_mutex_unlock(&LOCK_open);
- /* May be something modified consequently we have to invalidate cache */
- query_cache_invalidate3(thd, table->table, 0);
+ if (fatal_error)
+ table->table->s->version=0; // Force close of table
+ else if (open_for_modify)
+ {
+ pthread_mutex_lock(&LOCK_open);
+ remove_table_from_cache(thd, table->table->s->db,
+ table->table->s->table_name, RTFC_NO_FLAG);
+ pthread_mutex_unlock(&LOCK_open);
+ /* Something may be modified, that's why we have to invalidate cache */
+ query_cache_invalidate3(thd, table->table, 0);
+ }
}
close_thread_tables(thd);
table->table=0; // For query cache
--- 1.112/sql/table.h 2005-11-04 10:43:46 +01:00
+++ 1.113/sql/table.h 2005-11-14 17:01:01 +01:00
@@ -799,7 +799,15 @@
table_map used_tables; /* bitmap of tables in the nested join */
table_map not_null_tables; /* tables that rejects nulls */
struct st_join_table *first_nested;/* the first nested table in the plan */
- uint counter; /* to count tables in the nested join */
+ /*
+ Used to count tables in the nested join in 2 isolated places:
+ 1. In make_outerjoin_info().
+ 2. check_interleaving_with_nj/restore_prev_nj_state (these are called
+ by the join optimizer.
+ Before each use the counters are zeroed by reset_nj_counters.
+ */
+ uint counter;
+ nested_join_map nj_map; /* Bit used to identify this nested join*/
} NESTED_JOIN;
--- 1.54/sql/share/errmsg.txt 2005-11-04 10:43:45 +01:00
+++ 1.55/sql/share/errmsg.txt 2005-11-14 23:06:12 +01:00
@@ -5349,9 +5349,9 @@
ER_FAILED_ROUTINE_BREAK_BINLOG
eng "A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes"
ER_BINLOG_UNSAFE_ROUTINE
- eng "This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)"
+ eng "This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)"
ER_BINLOG_CREATE_ROUTINE_NEED_SUPER
- eng "You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)"
+ eng "You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)"
ER_EXEC_STMT_WITH_OPEN_CURSOR
eng "You can't execute a prepared statement which has an open cursor associated with it. Reset the statement to re-execute it."
ER_STMT_HAS_NO_OPEN_CURSOR
@@ -5405,23 +5405,21 @@
eng "The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner"
ER_SP_CANT_SET_AUTOCOMMIT
eng "Not allowed to set autocommit from a stored function or trigger"
-ER_NO_VIEW_USER
- eng "View definer is not fully qualified"
+ER_MALFORMED_DEFINER
+ eng "Definer is not fully qualified"
ER_VIEW_FRM_NO_USER
eng "View %-.64s.%-.64s has not definer information (old table format). Current user is used as definer. Please recreate view!"
ER_VIEW_OTHER_USER
- eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
+ eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
ER_NO_SUCH_USER
- eng "There is not %-.64s@%-.64s registered"
+ eng "There is no '%-.64s'@'%-.64s' registered"
ER_FORBID_SCHEMA_CHANGE
eng "Changing schema from '%-.64s' to '%-.64s' is not allowed."
ER_ROW_IS_REFERENCED_2 23000
eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)"
ER_NO_REFERENCED_ROW_2 23000
eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)"
-ER_BINLOG_ROW_LOGGING_FAILED
- eng "Writing one row to the row-based binary log failed"
-ER_BINLOG_ROW_WRONG_TABLE_DEF
- eng "Table definition on master and slave does not match"
ER_SP_BAD_VAR_SHADOW 42000
eng "Variable '%-.64s' must be quoted with `...`, or renamed"
+ER_TRG_NO_DEFINER
+ eng "No definer attribute for trigger '%-.64s'.'%-.64s'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger."
--- 1.43/mysql-test/mysql-test-run.pl 2005-11-04 10:43:44 +01:00
+++ 1.44/mysql-test/mysql-test-run.pl 2005-11-14 17:00:58 +01:00
@@ -930,7 +930,7 @@
}
$exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck");
$exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
- $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport");
+ $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport");
$exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
$exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
$exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
@@ -947,6 +947,7 @@
$path_client_bindir= mtr_path_exists("$glob_basedir/bin");
$exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck");
$exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
+ $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport");
$exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
$exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
$exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
@@ -2008,7 +2009,7 @@
mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir);
mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir);
mtr_add_arg($args, "%s--core", $prefix);
- mtr_add_arg($args, "%s--log-bin-trust-routine-creators", $prefix);
+ mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
@@ -2131,7 +2132,7 @@
mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix);
mtr_add_arg($args, "%s--sort_buffer=256K", $prefix);
mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix);
- mtr_add_arg($args, "%s--log-bin-trust-routine-creators", $prefix);
+ mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
if ( $opt_ssl_supported )
{
--- 1.6.3.1/mysql-test/r/rpl_ddl.result 2005-11-10 20:24:51 +01:00
+++ 1.11/mysql-test/r/rpl_stm_ddl.result 2005-11-14 17:00:59 +01:00
@@ -10,28 +10,28 @@
DROP DATABASE IF EXISTS mysqltest3;
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
-CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE= "InnoDB";
+CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE="InnoDB";
INSERT INTO mysqltest1.t1 SET f1= 0;
-CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t4 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t5 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t6 (f1 BIGINT) ENGINE= "InnoDB";
+CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t4 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t5 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t6 (f1 BIGINT) ENGINE="InnoDB";
CREATE INDEX my_idx6 ON mysqltest1.t6(f1);
-CREATE TABLE mysqltest1.t7 (f1 BIGINT) ENGINE= "InnoDB";
+CREATE TABLE mysqltest1.t7 (f1 BIGINT) ENGINE="InnoDB";
INSERT INTO mysqltest1.t7 SET f1= 0;
-CREATE TABLE mysqltest1.t8 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t9 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t10 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t11 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t12 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t13 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t14 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t15 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t16 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t17 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t18 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t19 (f1 BIGINT) ENGINE= "InnoDB";
+CREATE TABLE mysqltest1.t8 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t9 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t10 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t11 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t12 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t13 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t14 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t15 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t16 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t17 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t18 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t19 (f1 BIGINT) ENGINE="InnoDB";
CREATE TEMPORARY TABLE mysqltest1.t23 (f1 BIGINT);
SET AUTOCOMMIT = 0;
use mysqltest1;
--- 1.249/sql/ha_innodb.cc 2005-11-04 10:43:45 +01:00
+++ 1.250/sql/ha_innodb.cc 2005-11-14 17:00:59 +01:00
@@ -3010,8 +3010,8 @@
if (key_part->length > 0 && cs->mbmaxlen > 1) {
len = (ulint) cs->cset->well_formed_len(cs,
- src_start,
- src_start + key_part->length,
+ (const char *) src_start,
+ (const char *) src_start + key_part->length,
key_part->length / cs->mbmaxlen,
&error);
} else {
--- 1.103/include/my_global.h 2005-10-04 08:26:25 +02:00
+++ 1.104/include/my_global.h 2005-11-14 17:00:58 +01:00
@@ -553,6 +553,15 @@
#define O_NOFOLLOW 0
#endif
+/* additional file share flags for win32 */
+#ifdef __WIN__
+#define _SH_DENYRWD 0x110 /* deny read/write mode & delete */
+#define _SH_DENYWRD 0x120 /* deny write mode & delete */
+#define _SH_DENYRDD 0x130 /* deny read mode & delete */
+#define _SH_DENYDEL 0x140 /* deny delete only */
+#endif /* __WIN__ */
+
+
/* #define USE_RECORD_LOCK */
/* Unsigned types supported by the compiler */
--- 1.137/sql/set_var.cc 2005-09-27 22:13:20 +02:00
+++ 1.138/sql/set_var.cc 2005-11-14 17:00:59 +01:00
@@ -200,9 +200,12 @@
param_age_threshold));
sys_var_bool_ptr sys_local_infile("local_infile",
&opt_local_infile);
-sys_var_bool_ptr
+sys_var_trust_routine_creators
sys_trust_routine_creators("log_bin_trust_routine_creators",
- &trust_routine_creators);
+ &trust_function_creators);
+sys_var_bool_ptr
+sys_trust_function_creators("log_bin_trust_function_creators",
+ &trust_function_creators);
sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings);
sys_var_thd_ulong sys_long_query_time("long_query_time",
&SV::long_query_time);
@@ -722,6 +725,7 @@
&sys_innodb_commit_concurrency,
#endif
&sys_trust_routine_creators,
+ &sys_trust_function_creators,
&sys_engine_condition_pushdown,
#ifdef HAVE_NDBCLUSTER_DB
&sys_ndb_autoincrement_prefetch_sz,
@@ -867,7 +871,7 @@
#endif
{"log", (char*) &opt_log, SHOW_BOOL},
{"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
- {sys_trust_routine_creators.name,(char*) &sys_trust_routine_creators, SHOW_SYS},
+ {sys_trust_function_creators.name,(char*) &sys_trust_function_creators, SHOW_SYS},
{"log_error", (char*) log_error_file, SHOW_CHAR},
#ifdef HAVE_REPLICATION
{"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL},
@@ -3464,6 +3468,26 @@
return 0;
}
+
+void sys_var_trust_routine_creators::warn_deprecated(THD *thd)
+{
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DEPRECATED_SYNTAX,
+ ER(ER_WARN_DEPRECATED_SYNTAX), "log_bin_trust_routine_creators",
+ "log_bin_trust_function_creators");
+}
+
+void sys_var_trust_routine_creators::set_default(THD *thd, enum_var_type type)
+{
+ warn_deprecated(thd);
+ sys_var_bool_ptr::set_default(thd, type);
+}
+
+bool sys_var_trust_routine_creators::update(THD *thd, set_var *var)
+{
+ warn_deprecated(thd);
+ return sys_var_bool_ptr::update(thd, var);
+}
/****************************************************************************
Used templates
--- 1.4/mysql-test/t/rpl_trigger.test 2005-09-12 14:44:43 +02:00
+++ 1.5/mysql-test/t/rpl_trigger.test 2005-11-14 17:00:59 +01:00
@@ -88,12 +88,35 @@
select a=b && a=c from t1;
let $time=`select a from t1`;
+# Check that definer attribute is replicated properly:
+# - dump definers on the master;
+# - wait for the slave to synchronize with the master;
+# - dump definers on the slave;
+
+SELECT routine_name, definer
+FROM information_schema.routines;
+
+SELECT trigger_name, definer
+FROM information_schema.triggers;
+
save_master_pos;
connection slave;
sync_with_master;
--disable_query_log
select "--- On slave --" as "";
--enable_query_log
+
+# XXX: Definers of stored procedures and functions are not replicated. WL#2897
+# (Complete definer support in the stored routines) addresses this issue. So,
+# the result file is expected to be changed after implementation of this WL
+# item.
+
+SELECT routine_name, definer
+FROM information_schema.routines;
+
+SELECT trigger_name, definer
+FROM information_schema.triggers;
+
select a=b && a=c from t1;
--disable_query_log
eval select a='$time' as 'test' from t1;
--- 1.95/sql/sp.cc 2005-10-26 19:12:23 +02:00
+++ 1.96/sql/sp.cc 2005-11-14 17:01:00 +01:00
@@ -441,8 +441,8 @@
if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
goto done;
*sphp= thd->lex->sphead;
- (*sphp)->set_info((char *)definer, (uint)strlen(definer),
- created, modified, &chistics, sql_mode);
+ (*sphp)->set_definer((char*) definer, (uint) strlen(definer));
+ (*sphp)->set_info(created, modified, &chistics, sql_mode);
(*sphp)->optimize();
}
thd->lex->sql_command= oldcmd;
@@ -551,12 +551,13 @@
store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
system_charset_info);
- if (!trust_routine_creators && mysql_bin_log.is_open())
+ if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
+ !trust_function_creators && mysql_bin_log.is_open())
{
if (!sp->m_chistics->detistic)
{
/*
- Note that for a _function_ this test is not enough; one could use
+ Note that this test is not perfect; one could use
a non-deterministic read-only function in an update statement.
*/
enum enum_sp_data_access access=
--- 1.194/sql/sp_head.cc 2005-10-26 19:12:23 +02:00
+++ 1.195/sql/sp_head.cc 2005-11-14 17:01:00 +01:00
@@ -1578,21 +1578,9 @@
}
void
-sp_head::set_info(char *definer, uint definerlen,
- longlong created, longlong modified,
+sp_head::set_info(longlong created, longlong modified,
st_sp_chistics *chistics, ulong sql_mode)
{
- char *p= strchr(definer, '@');
- uint len;
-
- if (! p)
- p= definer; // Weird...
- len= p-definer;
- m_definer_user.str= strmake_root(mem_root, definer, len);
- m_definer_user.length= len;
- len= definerlen-len-1;
- m_definer_host.str= strmake_root(mem_root, p+1, len);
- m_definer_host.length= len;
m_created= created;
m_modified= modified;
m_chistics= (st_sp_chistics *) memdup_root(mem_root, (char*) chistics,
@@ -1605,6 +1593,34 @@
m_chistics->comment.length);
m_sql_mode= sql_mode;
}
+
+
+void
+sp_head::set_definer(char *definer, uint definerlen)
+{
+ char *p= strrchr(definer, '@');
+
+ if (!p)
+ {
+ m_definer_user.str= strmake_root(mem_root, "", 0);
+ m_definer_user.length= 0;
+
+ m_definer_host.str= strmake_root(mem_root, "", 0);
+ m_definer_host.length= 0;
+ }
+ else
+ {
+ const uint user_name_len= p - definer;
+ const uint host_name_len= definerlen - user_name_len - 1;
+
+ m_definer_user.str= strmake_root(mem_root, definer, user_name_len);
+ m_definer_user.length= user_name_len;
+
+ m_definer_host.str= strmake_root(mem_root, p + 1, host_name_len);
+ m_definer_host.length= host_name_len;
+ }
+}
+
void
sp_head::reset_thd_mem_root(THD *thd)
--- 1.162/sql/sql_prepare.cc 2005-11-04 10:43:45 +01:00
+++ 1.163/sql/sql_prepare.cc 2005-11-14 17:01:00 +01:00
@@ -2109,8 +2109,6 @@
were closed in the end of previous prepare or execute call.
*/
tables->table= 0;
- if (tables->nested_join)
- tables->nested_join->counter= 0;
if (tables->prep_on_expr)
{
| Thread |
|---|
| • bk commit into 5.0 tree (guilhem:1.1974) | guilhem | 14 Nov |