Below is the list of changes that have just been committed into a local
5.1 repository of mysqldev. When mysqldev 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.1854 05/04/08 13:27:31 mysqldev@stripped +34 -0
Merge
sql/ha_ndbcluster.cc
1.200 05/04/08 11:24:23 mysqldev@stripped +0 -0
Auto merged
sql/sql_table.cc
1.230 05/04/08 11:24:26 mysqldev@stripped +0 -0
Auto merged
sql/handler.h
1.134 05/04/08 11:24:24 mysqldev@stripped +0 -0
Auto merged
sql/handler.cc
1.155 05/04/08 11:24:24 mysqldev@stripped +0 -0
Auto merged
sql/ha_ndbcluster.h
1.85 05/04/08 11:24:23 mysqldev@stripped +0 -0
Auto merged
sql/sql_update.cc
1.153 05/04/08 11:24:26 mysqldev@stripped +0 -0
Auto merged
sql/sql_union.cc
1.115 05/04/08 11:24:26 mysqldev@stripped +0 -0
Auto merged
sql/sql_insert.cc
1.146 05/04/08 11:24:25 mysqldev@stripped +0 -0
Auto merged
sql/sql_class.h
1.229 05/04/08 11:24:25 mysqldev@stripped +0 -0
Auto merged
sql/sql_class.cc
1.175 05/04/08 11:24:25 mysqldev@stripped +0 -0
Auto merged
sql/sql_acl.h
1.35 05/04/08 11:24:25 mysqldev@stripped +0 -0
Auto merged
sql/sql_acl.cc
1.136 05/04/08 11:24:25 mysqldev@stripped +0 -0
Auto merged
sql/slave.cc
1.244 05/04/08 11:24:25 mysqldev@stripped +0 -1
Auto merged
sql/mysqld.cc
1.446 05/04/08 11:24:24 mysqldev@stripped +0 -0
Auto merged
sql/mysql_priv.h
1.285 05/04/08 11:24:24 mysqldev@stripped +0 -0
Auto merged
sql/log_event.h
1.110 05/04/08 11:24:24 mysqldev@stripped +0 -0
Auto merged
sql/log_event.cc
1.172 05/04/08 11:24:24 mysqldev@stripped +0 -0
Auto merged
sql/log.cc
1.160 05/04/08 11:24:24 mysqldev@stripped +0 -0
Auto merged
sql/item_sum.cc
1.136 05/04/08 11:24:24 mysqldev@stripped +0 -0
Auto merged
scripts/mysql_fix_privilege_tables.sql
1.17 05/04/08 11:24:23 mysqldev@stripped +0 -0
Auto merged
scripts/mysql_create_system_tables.sh
1.20 05/04/08 11:24:23 mysqldev@stripped +0 -0
Auto merged
ndb/src/kernel/blocks/dbdict/Dbdict.cpp
1.44 05/04/08 11:24:23 mysqldev@stripped +0 -0
Auto merged
mysql-test/t/user_var.test
1.26 05/04/08 11:24:23 mysqldev@stripped +0 -0
Auto merged
mysql-test/t/ctype_ucs.test
1.29 05/04/08 11:24:23 mysqldev@stripped +0 -0
Auto merged
mysql-test/r/user_var.result
1.32 05/04/08 11:24:23 mysqldev@stripped +0 -0
Auto merged
mysql-test/r/show_check.result
1.65 05/04/08 11:24:23 mysqldev@stripped +0 -0
Auto merged
mysql-test/r/rpl_timezone.result
1.13 05/04/08 11:24:22 mysqldev@stripped +0 -0
Auto merged
mysql-test/r/rpl_temporary.result
1.22 05/04/08 11:24:22 mysqldev@stripped +0 -0
Auto merged
mysql-test/r/ps_1general.result
1.32 05/04/08 11:24:22 mysqldev@stripped +0 -0
Auto merged
mysql-test/r/information_schema.result
1.41 05/04/08 11:24:22 mysqldev@stripped +0 -0
Auto merged
mysql-test/r/ctype_ucs.result
1.36 05/04/08 11:24:22 mysqldev@stripped +0 -0
Auto merged
mysql-test/mysql-test-run.sh
1.256 05/04/08 11:24:22 mysqldev@stripped +0 -0
Auto merged
configure.in
1.256 05/04/08 11:24:22 mysqldev@stripped +0 -0
Auto merged
BitKeeper/etc/logging_ok
1.282 05/04/08 11:24:14 mysqldev@stripped +0 -0
auto-union
# 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: mysqldev
# Host: production.mysql.com
# Root: /data0/mysqldev/lars/RESYNC
--- 1.255/configure.in 2005-04-05 18:18:05 +02:00
+++ 1.256/configure.in 2005-04-08 11:24:22 +02:00
@@ -19,7 +19,6 @@
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=1
NDB_VERSION_BUILD=0
-NDB_VERSION_STATUS="alpha"
# Set all version vars based on $VERSION. How do we do this more elegant ?
# Remember that regexps needs to quote [ and ] since this is run through m4
@@ -38,6 +37,7 @@
sinclude(config/ac-macros/compiler_flag.m4)
sinclude(config/ac-macros/ha_archive.m4)
sinclude(config/ac-macros/ha_berkeley.m4)
+sinclude(config/ac-macros/ha_blackhole.m4)
sinclude(config/ac-macros/ha_example.m4)
sinclude(config/ac-macros/ha_federated.m4)
sinclude(config/ac-macros/ha_innodb.m4)
@@ -353,7 +353,8 @@
then
if $CXX -v 2>&1 | grep 'version 3' > /dev/null 2>&1
then
- CXXFLAGS="$CXXFLAGS -DUSE_MYSYS_NEW -DDEFINE_CXA_PURE_VIRTUAL"
+ # Statically link the language support function's found in libsupc++.a
+ LIBS="$LIBS -lsupc++"
fi
fi
fi
@@ -2373,11 +2374,13 @@
AC_SUBST(readline_link)
AC_SUBST(readline_h_ln_cmd)
+MYSQL_CHECK_BIG_TABLES
MYSQL_CHECK_BDB
MYSQL_CHECK_INNODB
MYSQL_CHECK_EXAMPLEDB
MYSQL_CHECK_ARCHIVEDB
MYSQL_CHECK_CSVDB
+MYSQL_CHECK_BLACKHOLEDB
MYSQL_CHECK_NDBCLUSTER
MYSQL_CHECK_FEDERATED
--- 1.255/mysql-test/mysql-test-run.sh 2005-03-22 12:30:42 +01:00
+++ 1.256/mysql-test/mysql-test-run.sh 2005-04-08 11:24:22 +02:00
@@ -222,6 +222,7 @@
EXTRA_MASTER_OPT=""
EXTRA_MYSQL_TEST_OPT=""
EXTRA_MYSQLDUMP_OPT=""
+EXTRA_MYSQLSHOW_OPT=""
EXTRA_MYSQLBINLOG_OPT=""
USE_RUNNING_SERVER=0
USE_NDBCLUSTER=@USE_NDBCLUSTER@
@@ -238,7 +239,7 @@
SLEEP_TIME_FOR_FIRST_MASTER=400 # Enough time to create innodb tables
SLEEP_TIME_FOR_SECOND_MASTER=400
SLEEP_TIME_FOR_FIRST_SLAVE=400
-SLEEP_TIME_FOR_SECOND_SLAVE=30
+SLEEP_TIME_FOR_SECOND_SLAVE=300
CHARACTER_SET=latin1
DBUSER=""
START_WAIT_TIMEOUT=10
@@ -453,6 +454,8 @@
--debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqltest.trace"
EXTRA_MYSQLDUMP_OPT="$EXTRA_MYSQLDUMP_OPT \
--debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqldump.trace"
+ EXTRA_MYSQLSHOW_OPT="$EXTRA_MYSQLSHOW_OPT \
+ --debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqlshow.trace"
EXTRA_MYSQLBINLOG_OPT="$EXTRA_MYSQLBINLOG_OPT \
--debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqlbinlog.trace"
EXTRA_MYSQL_CLIENT_TEST_OPT="--debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysql_client_test.trace"
@@ -556,6 +559,11 @@
else
MYSQL_DUMP="$BASEDIR/client/mysqldump"
fi
+ if [ -f "$BASEDIR/client/.libs/mysqlshow" ] ; then
+ MYSQL_SHOW="$BASEDIR/client/.libs/mysqlshow"
+ else
+ MYSQL_SHOW="$BASEDIR/client/mysqlshow"
+ fi
if [ -f "$BASEDIR/client/.libs/mysqlbinlog" ] ; then
MYSQL_BINLOG="$BASEDIR/client/.libs/mysqlbinlog"
else
@@ -627,6 +635,7 @@
fi
MYSQL_TEST="$CLIENT_BINDIR/mysqltest"
MYSQL_DUMP="$CLIENT_BINDIR/mysqldump"
+ MYSQL_SHOW="$CLIENT_BINDIR/mysqlshow"
MYSQL_BINLOG="$CLIENT_BINDIR/mysqlbinlog"
MYSQLADMIN="$CLIENT_BINDIR/mysqladmin"
WAIT_PID="$CLIENT_BINDIR/mysql_waitpid"
@@ -697,10 +706,11 @@
MYSQL_CLIENT_TEST="$MYSQL_CLIENT_TEST --no-defaults --testcase --user=root
--socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT --silent $EXTRA_MYSQL_CLIENT_TEST_OPT"
MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD
$EXTRA_MYSQLDUMP_OPT"
+MYSQL_SHOW="$MYSQL_SHOW -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD
$EXTRA_MYSQLSHOW_OPT"
MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR
--character-sets-dir=$CHARSETSDIR $EXTRA_MYSQLBINLOG_OPT"
MYSQL_FIX_SYSTEM_TABLES="$MYSQL_FIX_SYSTEM_TABLES --no-defaults --host=localhost
--port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD
--basedir=$BASEDIR --bindir=$CLIENT_BINDIR --verbose"
MYSQL="$MYSQL --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root
--password=$DBPASSWD"
-export MYSQL MYSQL_DUMP MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES
+export MYSQL MYSQL_DUMP MYSQL_SHOW MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES
export CLIENT_BINDIR MYSQL_CLIENT_TEST CHARSETSDIR
export NDB_TOOLS_DIR
export NDB_MGM
@@ -731,7 +741,7 @@
XTERM=`which xterm`
fi
-export MYSQL MYSQL_DUMP MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES CLIENT_BINDIR MASTER_MYSOCK
+export MYSQL MYSQL_DUMP MYSQL_SHOW MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES CLIENT_BINDIR
MASTER_MYSOCK
#++
# Function Definitions
--- 1.154/sql/handler.cc 2005-03-30 15:00:27 +02:00
+++ 1.155/sql/handler.cc 2005-04-08 11:24:24 +02:00
@@ -25,6 +25,7 @@
#include "ha_heap.h"
#include "ha_myisam.h"
#include "ha_myisammrg.h"
+#include "bitvector.h"
#ifdef HAVE_ISAM
#include "ha_isam.h"
#include "ha_isammrg.h"
@@ -1738,6 +1739,13 @@
# Error
*/
+#ifdef USE_PREPARE_CODE
+int handler::prepare_delete_table(const char *name)
+{
+ return 0;
+}
+#endif
+
int handler::delete_table(const char *name)
{
int error= 0;
@@ -1760,6 +1768,13 @@
}
+#ifdef USE_PREPARE_CODE
+int handler::prepare_rename_table(const char * from, const char * to)
+{
+ return 0;
+}
+#endif
+
int handler::rename_table(const char * from, const char * to)
{
DBUG_ENTER("handler::rename_table");
@@ -2400,4 +2415,125 @@
*ext= 0;
}
return &known_extensions;
+}
+
+int handler::
+ha_write_row(byte *buf)
+{
+ DBUG_ENTER("ha_write_row");
+ DBUG_PRINT("enter", ("row: 0x%0x", buf));
+#ifndef DBUG_OFF
+ THD* thd = current_thd;
+ DBUG_PRINT("info", ("thd->query_id=%lu", thd->query_id));
+ for (size_t i = 0 ; i < table->s->fields ; ++i)
+ {
+ DBUG_PRINT("info", ("Field '%s': query_id=%lu, offset=%d, ptr=%p",
+ table->field[i]->field_name,
+ table->field[i]->query_id,
+ table->field[i]->offset(),
+ table->field[i]->ptr));
+ }
+#endif
+ DBUG_PRINT("info", ("Writing row to actual handler"));
+ if (int error = write_row(buf)) {
+ DBUG_PRINT("exit", ("error = %d", error));
+ DBUG_RETURN(error);
+ }
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ DBUG_PRINT("info", ("Writing row to THD"));
+ if (table->s->tmp_table == NO_TMP_TABLE
+ && !this->is_injective())
+ {
+ bitvector const cols(table->s->fields, true);
+ thd->write_row(table, cols, buf);
+ }
+#endif
+ DBUG_PRINT("exit", ("error = %d", 0));
+ DBUG_RETURN(0);
+}
+
+int handler::
+ha_update_row(const byte *old_data, byte *new_data)
+{
+ DBUG_ENTER("ha_update_row");
+ DBUG_PRINT("enter", ("before: 0x%0x; after: 0x%0x", old_data, new_data));
+#ifndef DBUG_OFF
+ THD* thd = current_thd;
+ DBUG_PRINT("info", ("thd->query_id=%lu", thd->query_id));
+ for (size_t i = 0 ; i < table->s->fields ; ++i)
+ {
+ DBUG_PRINT("info", ("Field '%s': query_id=%lu, offset=%d, ptr=%p",
+ table->field[i]->field_name,
+ table->field[i]->query_id,
+ table->field[i]->offset(),
+ table->field[i]->ptr));
+ }
+#endif
+ if (int error = update_row(old_data, new_data)) {
+ DBUG_PRINT("exit", ("error = %d", error));
+ DBUG_RETURN(error);
+ }
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ if (table->s->tmp_table == NO_TMP_TABLE
+ && !this->is_injective())
+ {
+ bitvector const cols(table->s->fields, true);
+ thd->update_row(table, cols, old_data, new_data);
+ }
+#endif
+ DBUG_PRINT("exit", ("error = %d", 0));
+ DBUG_RETURN(0);
+}
+
+int handler::
+ha_delete_row(const byte *buf)
+{
+ DBUG_ENTER("ha_delete_row");
+ DBUG_PRINT("enter", ("row: 0x%0x", buf));
+#ifndef DBUG_OFF
+ THD* thd = current_thd;
+ DBUG_PRINT("info", ("thd->query_id=%lu", thd->query_id));
+ for (size_t i = 0 ; i < table->s->fields ; ++i)
+ {
+ DBUG_PRINT("info", ("Field '%s': query_id=%lu, offset=%d, ptr=%p",
+ table->field[i]->field_name,
+ table->field[i]->query_id,
+ table->field[i]->offset(),
+ table->field[i]->ptr));
+ }
+#endif
+ if (int error = delete_row(buf)) {
+ DBUG_PRINT("exit", ("error = %d", error));
+ DBUG_RETURN(error);
+ }
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ if (table->s->tmp_table == NO_TMP_TABLE
+ && !this->is_injective())
+ {
+ bitvector const cols(table->s->fields, true);
+ thd->delete_row(table, cols, buf);
+ }
+#endif
+ DBUG_PRINT("exit", ("error = %d", 0));
+ DBUG_RETURN(0);
+}
+
+int handler::
+ha_stmt_begin()
+{
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ return current_thd->transaction_begin();
+#else
+ return 0;
+#endif
+}
+
+int handler::
+ha_stmt_end()
+{
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ return current_thd->transaction_end();
+#else
+ return 0;
+#endif
}
--- 1.133/sql/handler.h 2005-03-25 21:38:03 +01:00
+++ 1.134/sql/handler.h 2005-04-08 11:24:24 +02:00
@@ -150,6 +150,9 @@
/* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */
#define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1
+// Forward declarations
+class bitvector;
+
enum db_type
{
DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
@@ -406,6 +409,7 @@
} HANDLER_BUFFER;
+
class handler :public Sql_alloc
{
protected:
@@ -543,11 +547,21 @@
uint get_index(void) const { return active_index; }
virtual int open(const char *name, int mode, uint test_if_locked)=0;
virtual int close(void)=0;
- virtual int write_row(byte * buf) { return HA_ERR_WRONG_COMMAND; }
- virtual int update_row(const byte * old_data, byte * new_data)
- { return HA_ERR_WRONG_COMMAND; }
- virtual int delete_row(const byte * buf)
- { return HA_ERR_WRONG_COMMAND; }
+
+ int ha_write_row(byte *buf);
+ int ha_update_row(const byte *old_data, byte *new_data);
+ int ha_delete_row(const byte *buf);
+
+ int ha_stmt_begin();
+ int ha_stmt_end();
+
+ /*
+ If the handler does it's own injection of the rows, this member function
+ should return 'true'. An alternative would be to use a set of replication
+ flags, which might be implemented to be faster.
+ */
+ virtual bool is_injective() const { return false; }
+
virtual int index_read(byte * buf, const byte * key,
uint key_len, enum ha_rkey_function find_flag)
{ return HA_ERR_WRONG_COMMAND; }
@@ -698,9 +712,14 @@
default rename_table() and delete_table() rename/delete files with a
given name and extensions from bas_ext()
*/
- virtual int rename_table(const char *from, const char *to);
+#define USE_PREPARE_CODE
+#ifdef USE_PREPARE_CODE
+ virtual int prepare_rename_table(const char *from, const char *to);
+ virtual int prepare_delete_table(const char *name);
+#endif
+ virtual int rename_table(const char *from, const char *to);
virtual int delete_table(const char *name);
-
+
virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
/* lock_count() can be more than one if the table is a MERGE */
@@ -732,7 +751,7 @@
{
return memcmp(ref1, ref2, ref_length);
}
-
+
/*
Condition pushdown to storage engines
*/
@@ -766,6 +785,18 @@
Pops the top if condition stack, if stack is not empty
*/
virtual void cond_pop() { return; };
+
+private:
+ /*
+ Row-level primitives for storage engines.
+ These should be overridden by the storage engine class. To call
+ these methods, use the corresponding 'ha_*' method above.
+ */
+ virtual int write_row(byte * buf) { return HA_ERR_WRONG_COMMAND; }
+ virtual int update_row(const byte * old_data, byte * new_data)
+ { return HA_ERR_WRONG_COMMAND; }
+ virtual int delete_row(const byte * buf)
+ { return HA_ERR_WRONG_COMMAND; }
};
/* Some extern variables used with handlers */
--- 1.135/sql/item_sum.cc 2005-03-30 15:57:49 +02:00
+++ 1.136/sql/item_sum.cc 2005-04-08 11:24:24 +02:00
@@ -2370,7 +2370,7 @@
*/
return tree->unique_add(table->record[0] + table->s->null_bytes);
}
- if ((error= table->file->write_row(table->record[0])) &&
+ if ((error= table->file->ha_write_row(table->record[0])) &&
error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE)
return TRUE;
--- 1.159/sql/log.cc 2005-04-01 22:17:22 +02:00
+++ 1.160/sql/log.cc 2005-04-08 11:24:24 +02:00
@@ -348,8 +348,9 @@
MYSQL_LOG::MYSQL_LOG()
: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), description_event_for_exec(0),
- description_event_for_queue(0)
+ need_start_event(1), prepared_xids(0),
+ m_table_map(NULL), m_next_table_id(0),
+ description_event_for_exec(0), description_event_for_queue(0)
{
/*
We don't want to initialize LOCK_Log here as such initialization depends on
@@ -410,6 +411,7 @@
no_auto_events = no_auto_events_arg;
max_size=max_size_arg;
DBUG_PRINT("info",("log_type: %d max_size: %lu", log_type, max_size));
+
DBUG_VOID_RETURN;
}
@@ -1550,9 +1552,15 @@
bool MYSQL_LOG::write(Log_event *event_info)
{
- THD *thd= event_info->thd;
+ THD *thd=event_info->thd;
bool error= 1;
- DBUG_ENTER("MYSQL_LOG::write(Log_event *)");
+ DBUG_ENTER("MYSQL_LOG::write(Log_event*)");
+
+ /*
+ Let the event decide if it want to go to the binlog.
+ */
+ if (!event_info->write_to_binlog())
+ DBUG_RETURN(0); // Silently succeed
pthread_mutex_lock(&LOCK_log);
@@ -1583,15 +1591,21 @@
#ifdef USING_TRANSACTIONS
/*
- Should we write to the binlog cache or to the binlog on disk?
- Write to the binlog cache if:
- - it is already not empty (meaning we're in a transaction; note that the
- present event could be about a non-transactional table, but still we need
- to write to the binlog cache in that case to handle updates to mixed
- trans/non-trans table types the best possible in binlogging)
+ Should we write to the binlog cache or to the binlog on disk? Write to
+ the binlog cache if the statement can be cached (can_be_cached() ==
+ true) and the binlog cache:
+ - is already not empty (meaning we're in a transaction; note that the
+ present event could be about a non-transactional table, but still we
+ need to write to the binlog cache in that case to handle updates to
+ mixed trans/non-trans table types the best possible in binlogging)
- or if the event asks for it (cache_stmt == true).
*/
+#if 0
+ // Disabled writing directly to the log, since it doesn't work right now.
+ if (opt_using_transactions && thd && event_info->can_be_cached())
+#else
if (opt_using_transactions && thd)
+#endif
{
IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
@@ -1686,6 +1700,7 @@
if (file == &log_file) // we are writing to the real log (disk)
{
+ DBUG_PRINT("info", ("Flushing cache %p", file));
if (flush_io_cache(file) || sync_binlog(file))
goto err;
}
@@ -2244,6 +2259,61 @@
DBUG_VOID_RETURN;
}
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+
+ulong MYSQL_LOG::
+get_table_id(TABLE* table)
+{
+ DBUG_ENTER("MYSQL_LOG::get_table_id(TABLE*)");
+ DBUG_PRINT("enter", ("table=%p", table));
+ DBUG_ASSERT(table != NULL);
+
+ // Have to create it here since it relies on my_malloc, which requires
+ // my_init() to have been executed prior to this.
+ if (m_table_map == NULL)
+ m_table_map = new table_mapping;
+
+ DBUG_ASSERT(m_table_map != NULL);
+
+ ulong tid = m_table_map->get_table_id(table);
+ if (tid == table_mapping::NO_TABLE) {
+ // We can't use the number of tables in the list since the highest table
+ // id might be larger than the number of elements in the list.
+ tid = m_next_table_id++;
+
+ // There is one reserved number that cannot be used.
+ if (tid == table_mapping::NO_TABLE)
+ tid = m_next_table_id++;
+
+ m_table_map->set_table(tid, table);
+ }
+ DBUG_PRINT("return", ("table_id=%d", tid));
+ DBUG_RETURN(tid);
+}
+
+int MYSQL_LOG::
+is_table_mapped(TABLE* table) const
+{
+ DBUG_ASSERT(table != NULL);
+
+ // Have to create it here since it relies on my_malloc, which requires
+ // my_init() to have been executed prior to this.
+ if (m_table_map == NULL)
+ m_table_map = new table_mapping;
+
+ DBUG_ASSERT(m_table_map != NULL);
+ return m_table_map->get_table_id(table) != table_mapping::NO_TABLE;
+}
+
+void MYSQL_LOG::
+clear_table_mappings()
+{
+ DBUG_ASSERT(m_table_map != NULL);
+ m_table_map->clear_tables();
+}
+
+#endif // !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
#ifdef __NT__
void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
--- 1.171/sql/log_event.cc 2005-04-01 13:40:13 +02:00
+++ 1.172/sql/log_event.cc 2005-04-08 11:24:24 +02:00
@@ -21,6 +21,7 @@
#endif
#include "mysql_priv.h"
#include "slave.h"
+#include "rpl_filter.h"
#include <my_dir.h>
#endif /* MYSQL_CLIENT */
@@ -510,8 +511,6 @@
field_list->push_back(new Item_empty_string("Info", 20));
}
-#endif /* !MYSQL_CLIENT */
-
/*
Log_event::write()
@@ -599,7 +598,6 @@
*/
-#ifndef MYSQL_CLIENT
int Log_event::read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock)
{
@@ -981,6 +979,7 @@
}
#endif
+#ifndef MYSQL_CLIENT
/*
Query_log_event::write()
@@ -998,7 +997,8 @@
1+8+ // code of sql_mode and sql_mode
1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1+4+ // code of autoinc and the 2 autoinc variables
- 1+6 // code of charset and charset
+ 1+6+ // code of charset and charset
+ 1+1+MAX_TIME_ZONE_NAME_LENGTH // code of tz and tz length and tz name
], *start, *start_of_status;
ulong event_length;
@@ -1055,37 +1055,40 @@
start_of_status= start= buf+QUERY_HEADER_LEN;
if (flags2_inited)
{
- *(start++)= Q_FLAGS2_CODE;
+ *start++= Q_FLAGS2_CODE;
int4store(start, flags2);
start+= 4;
}
if (sql_mode_inited)
{
- *(start++)= Q_SQL_MODE_CODE;
+ *start++= Q_SQL_MODE_CODE;
int8store(start, (ulonglong)sql_mode);
start+= 8;
}
- if (catalog_len >= 0) // i.e. "catalog inited" (false for 4.0 events)
+ if (catalog_len) // i.e. "catalog inited" (false for 4.0 events)
{
- *(start++)= Q_CATALOG_CODE;
- *(start++)= (uchar) catalog_len;
+ *start++= Q_CATALOG_NZ_CODE;
+ *start++= (uchar) catalog_len;
bmove(start, catalog, catalog_len);
start+= catalog_len;
/*
- We write a \0 at the end. As we also have written the length, it's
- apparently useless; but in fact it enables us to just do
- catalog= a_pointer_to_the_buffer_of_the_read_event
- later in the slave SQL thread.
- If we didn't have the \0, we would need to memdup to build the catalog in
- the slave SQL thread.
- And still the interest of having the length too is that in the slave SQL
- thread we immediately know at which position the catalog ends (no need to
- search for '\0'. In other words: length saves search, \0 saves mem alloc,
- at the cost of 1 redundant byte on the disk.
- Note that this is only a fix until we change 'catalog' to LEX_STRING
- (then we won't need the \0).
+ In 5.0.x where x<4 masters we used to store the end zero here. This was
+ a waste of one byte so we don't do it in x>=4 masters. We change code to
+ Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
+ of this x>=4 master segfault (expecting a zero when there is
+ none). Remaining compatibility problems are: the older slave will not
+ find the catalog; but it is will not crash, and it's not an issue
+ that it does not find the catalog as catalogs were not used in these
+ older MySQL versions (we store it in binlog and read it from relay log
+ but do nothing useful with it). What is an issue is that the older slave
+ will stop processing the Q_* blocks (and jumps to the db/query) as soon
+ as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
+ Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
+ various ways. Documented that you should not mix alpha/beta versions if
+ they are not exactly the same version, with example of 5.0.3->5.0.2 and
+ 5.0.4->5.0.3. If replication is from older to new, the new will
+ recognize Q_CATALOG_CODE and have no problem.
*/
- *(start++)= '\0';
}
if (auto_increment_increment != 1)
{
@@ -1096,15 +1099,24 @@
}
if (charset_inited)
{
- *(start++)= Q_CHARSET_CODE;
+ *start++= Q_CHARSET_CODE;
memcpy(start, charset, 6);
start+= 6;
}
+ if (time_zone_len)
+ {
+ /* In the TZ sys table, column Name is of length 64 so this should be ok */
+ DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
+ *start++= Q_TIME_ZONE_CODE;
+ *start++= time_zone_len;
+ memcpy(start, time_zone_str, time_zone_len);
+ start+= time_zone_len;
+ }
/*
Here there could be code like
if (command-line-option-which-says-"log_this_variable" && inited)
{
- *(start++)= Q_THIS_VARIABLE_CODE;
+ *start++= Q_THIS_VARIABLE_CODE;
int4store(start, this_variable);
start+= 4;
}
@@ -1133,8 +1145,6 @@
/*
Query_log_event::Query_log_event()
*/
-
-#ifndef MYSQL_CLIENT
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
ulong query_length, bool using_trans,
bool suppress_use)
@@ -1175,6 +1185,18 @@
int2store(charset, thd_arg->variables.character_set_client->number);
int2store(charset+2, thd_arg->variables.collation_connection->number);
int2store(charset+4, thd_arg->variables.collation_server->number);
+ if (thd_arg->time_zone_used)
+ {
+ /*
+ Note that our event becomes dependent on the Time_zone object
+ representing the time zone. Fortunately such objects are never deleted
+ or changed during mysqld's lifetime.
+ */
+ time_zone_len= thd_arg->variables.time_zone->get_name()->length();
+ time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
+ }
+ else
+ time_zone_len= 0;
DBUG_PRINT("info",("Query_log_event has flags2=%lu sql_mode=%lu",flags2,sql_mode));
}
#endif /* MYSQL_CLIENT */
@@ -1188,15 +1210,18 @@
Query_log_event::Query_log_event(const char* buf, uint event_len,
const Format_description_log_event *description_event,
Log_event_type event_type)
- :Log_event(buf, description_event), data_buf(0), query(NullS), catalog(NullS),
+ :Log_event(buf, description_event), data_buf(0), query(NullS),
db(NullS), catalog_len(0), status_vars_len(0),
flags2_inited(0), sql_mode_inited(0), charset_inited(0),
- auto_increment_increment(1), auto_increment_offset(1)
+ auto_increment_increment(1), auto_increment_offset(1),
+ time_zone_len(0)
{
ulong data_len;
uint32 tmp;
uint8 common_header_len, post_header_len;
- const char *start, *end;
+ char *start;
+ const char *end;
+ bool catalog_nz= 1;
DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
common_header_len= description_event->common_header_len;
@@ -1216,7 +1241,7 @@
slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
- db_len = (uint)buf[Q_DB_LEN_OFFSET];
+ db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
/*
@@ -1242,7 +1267,7 @@
/* variable-part: the status vars; only in MySQL 5.0 */
start= (char*) (buf+post_header_len);
- end= (char*) (start+status_vars_len);
+ end= (const char*) (start+status_vars_len);
for (const uchar* pos= (const uchar*) start; pos < (const uchar*) end;)
{
switch (*pos++) {
@@ -1264,11 +1289,10 @@
pos+= 8;
break;
}
- case Q_CATALOG_CODE:
- catalog_len= *pos;
- if (catalog_len)
- catalog= (char*) pos+1; // Will be copied later
- pos+= catalog_len+2;
+ case Q_CATALOG_NZ_CODE:
+ if ((catalog_len= *pos))
+ catalog= (char*) pos+1; // Will be copied later
+ pos+= catalog_len+1;
break;
case Q_AUTO_INCREMENT:
auto_increment_increment= uint2korr(pos);
@@ -1282,32 +1306,60 @@
pos+= 6;
break;
}
+ case Q_TIME_ZONE_CODE:
+ {
+ if ((time_zone_len= *pos))
+ time_zone_str= (char *)(pos+1);
+ pos+= time_zone_len+1;
+ break;
+ }
+ case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
+ if ((catalog_len= *pos))
+ catalog= (char*) pos+1; // Will be copied later
+ pos+= catalog_len+2; // leap over end 0
+ catalog_nz= 0; // catalog has end 0 in event
+ break;
default:
/* That's why you must write status vars in growing order of code */
DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
code: %u), skipping the rest of them", (uint) *(pos-1)));
- pos= (const uchar*) end; // Break look
+ pos= (const uchar*) end; // Break loop
}
}
- /* A 2nd variable part; this is common to all versions */
-
- if (!(start= data_buf = (char*) my_malloc(catalog_len + data_len +2, MYF(MY_WME))))
+ if (!(start= data_buf = (char*) my_malloc(catalog_len + 1 +
+ time_zone_len + 1 +
+ data_len + 1, MYF(MY_WME))))
DBUG_VOID_RETURN;
- if (catalog) // If catalog is given
+ if (catalog_len) // If catalog is given
+ {
+ if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
+ {
+ memcpy(start, catalog, catalog_len);
+ catalog= start;
+ start+= catalog_len;
+ *start++= 0;
+ }
+ else
+ {
+ memcpy(start, catalog, catalog_len+1); // copy end 0
+ catalog= start;
+ start+= catalog_len+1;
+ }
+ }
+ if (time_zone_len)
{
- memcpy((char*) start, catalog, catalog_len+1); // Copy name and end \0
- catalog= start;
- start+= catalog_len+1;
+ memcpy(start, time_zone_str, time_zone_len);
+ time_zone_str= start;
+ start+= time_zone_len;
+ *start++= 0;
}
+ /* A 2nd variable part; this is common to all versions */
memcpy((char*) start, end, data_len); // Copy db and query
- ((char*) start)[data_len]= '\0'; // End query with \0 (For safetly)
+ start[data_len]= '\0'; // End query with \0 (For safetly)
db= start;
query= start + db_len + 1;
q_len= data_len - db_len -1;
- /* This is used to detect wrong parsing. Could be removed in the future. */
- DBUG_PRINT("info", ("catalog: '%s' len: %u db: '%s' len: %u q_len: %lu",
- catalog, (uint) catalog_len, db, (uint) db_len,q_len));
DBUG_VOID_RETURN;
}
@@ -1415,6 +1467,8 @@
last_event_info->auto_increment_offset= auto_increment_offset;
}
+ /* TODO: print the catalog when we feature SET CATALOG */
+
if (likely(charset_inited))
{
if (unlikely(!last_event_info->charset_inited)) /* first Query event */
@@ -1435,6 +1489,14 @@
memcpy(last_event_info->charset, charset, 6);
}
}
+ if (time_zone_len)
+ {
+ if (bcmp(last_event_info->time_zone_str, time_zone_str, time_zone_len+1))
+ {
+ fprintf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
+ memcpy(last_event_info->time_zone_str, time_zone_str, time_zone_len+1);
+ }
+ }
}
@@ -1468,9 +1530,9 @@
alloced block (see Query_log_event::exec_event()). Same for thd->db.
Thank you.
*/
- thd->catalog= (char*) catalog;
+ thd->catalog= catalog_len ? (char *) catalog : (char *)"";
thd->db_length= db_len;
- thd->db= (char*) rewrite_db(db, &thd->db_length);
+ thd->db= (char *) rpl_filter->get_rewrite_db(db, &thd->db_length);
thd->variables.auto_increment_increment= auto_increment_increment;
thd->variables.auto_increment_offset= auto_increment_offset;
@@ -1489,7 +1551,7 @@
clear_all_errors(thd, rli);
- if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
+ if (rpl_filter->db_ok(thd->db))
{
thd->set_time((time_t)when);
thd->query_length= q_len_arg;
@@ -1538,20 +1600,28 @@
get_charset(uint2korr(charset+4), MYF(MY_WME))))
{
/*
- We updated the thd->variables with nonsensical values (0), and the
- thread is not guaranteed to terminate now (as it may be configured
- to ignore EE_UNKNOWN_CHARSET);if we're going to execute a next
- statement we'll have a new charset info with it, so no problem to
- have stored 0 in thd->variables. But we invalidate cached
- charset to force a check next time (otherwise if next time
- charset is unknown again we won't detect it).
+ We updated the thd->variables with nonsensical values (0). Let's
+ set them to something safe (i.e. which avoids crash), and we'll
+ stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
+ ignore this error).
*/
- rli->cached_charset_invalidate();
+ set_slave_thread_default_charset(thd, rli);
goto compare_errors;
}
thd->update_charset(); // for the charset change to take effect
}
}
+ if (time_zone_len)
+ {
+ String tmp(time_zone_str, time_zone_len, &my_charset_bin);
+ if (!(thd->variables.time_zone=
+ my_tz_find_with_opening_tz_tables(thd, &tmp)))
+ {
+ my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
+ thd->variables.time_zone= global_system_variables.time_zone;
+ goto compare_errors;
+ }
+ }
/* Execute the query (note that we bypass dispatch_command()) */
mysql_parse(thd, thd->query, thd->query_length);
@@ -1776,6 +1846,7 @@
Start_log_event_v3::write()
*/
+#ifndef MYSQL_CLIENT
bool Start_log_event_v3::write(IO_CACHE* file)
{
char buff[START_V3_HEADER_LEN];
@@ -1785,6 +1856,7 @@
return (write_header(file, sizeof(buff)) ||
my_b_safe_write(file, (byte*) buff, sizeof(buff)));
}
+#endif
/*
@@ -2004,7 +2076,7 @@
DBUG_VOID_RETURN;
}
-
+#ifndef MYSQL_CLIENT
bool Format_description_log_event::write(IO_CACHE* file)
{
/*
@@ -2021,6 +2093,7 @@
return (write_header(file, sizeof(buff)) ||
my_b_safe_write(file, buff, sizeof(buff)));
}
+#endif
/*
SYNOPSIS
@@ -2041,6 +2114,7 @@
delete rli->relay_log.description_event_for_exec;
rli->relay_log.description_event_for_exec= this;
+#ifdef USING_TRANSACTIONS
/*
As a transaction NEVER spans on 2 or more binlogs:
if we have an active transaction at this point, the master died
@@ -2062,6 +2136,7 @@
"to its binary log.");
end_trans(thd, ROLLBACK);
}
+#endif
/*
If this event comes from ourselves, there is no cleaning task to perform,
we don't call Start_log_event_v3::exec_event() (this was just to update the
@@ -2237,6 +2312,8 @@
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
+#ifndef MYSQL_CLIENT
+
/*
Load_log_event::write_data_header()
*/
@@ -2278,7 +2355,6 @@
Load_log_event::Load_log_event()
*/
-#ifndef MYSQL_CLIENT
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
const char *db_arg, const char *table_name_arg,
List<Item> &fields_arg,
@@ -2598,7 +2674,7 @@
bool use_rli_only_for_errors)
{
thd->db_length= db_len;
- thd->db= (char*) rewrite_db(db, &thd->db_length);
+ thd->db= (char *) rpl_filter->get_rewrite_db(db, &thd->db_length);
DBUG_ASSERT(thd->query == 0);
thd->query_length= 0; // Should not be needed
thd->query_error= 0;
@@ -2627,7 +2703,7 @@
al. Another way is do the filtering in the I/O thread (more efficient: no
disk writes at all).
*/
- if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
+ if (rpl_filter->db_ok(thd->db))
{
thd->set_time((time_t)when);
VOID(pthread_mutex_lock(&LOCK_thread_count));
@@ -2649,7 +2725,7 @@
tables.updating= 1;
// the table will be opened in mysql_load
- if (table_rules_on && !tables_ok(thd, &tables))
+ if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db,
&tables))
{
// TODO: this is a bug - this needs to be moved to the I/O thread
if (net)
@@ -2892,6 +2968,7 @@
Rotate_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Rotate_log_event::write(IO_CACHE* file)
{
char buf[ROTATE_HEADER_LEN];
@@ -2900,7 +2977,7 @@
my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
}
-
+#endif
/*
Rotate_log_event::exec_event()
@@ -2958,17 +3035,10 @@
master is 4.0 then the events are in the slave's format (conversion).
*/
set_slave_thread_options(thd);
+ set_slave_thread_default_charset(thd, rli);
thd->variables.sql_mode= global_system_variables.sql_mode;
thd->variables.auto_increment_increment=
thd->variables.auto_increment_offset= 1;
- thd->variables.character_set_client=
- global_system_variables.character_set_client;
- thd->variables.collation_connection=
- global_system_variables.collation_connection;
- thd->variables.collation_server=
- global_system_variables.collation_server;
- thd->update_charset();
- rli->cached_charset_invalidate();
}
pthread_mutex_unlock(&rli->data_lock);
pthread_cond_broadcast(&rli->data_cond);
@@ -3030,6 +3100,7 @@
Intvar_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Intvar_log_event::write(IO_CACHE* file)
{
byte buf[9];
@@ -3038,6 +3109,7 @@
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
+#endif
/*
@@ -3122,6 +3194,7 @@
}
+#ifndef MYSQL_CLIENT
bool Rand_log_event::write(IO_CACHE* file)
{
byte buf[16];
@@ -3130,6 +3203,7 @@
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
+#endif
#ifdef MYSQL_CLIENT
@@ -3193,11 +3267,13 @@
}
+#ifndef MYSQL_CLIENT
bool Xid_log_event::write(IO_CACHE* file)
{
return write_header(file, sizeof(xid)) ||
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
}
+#endif
#ifdef MYSQL_CLIENT
@@ -3331,6 +3407,7 @@
}
+#ifndef MYSQL_CLIENT
bool User_var_log_event::write(IO_CACHE* file)
{
char buf[UV_NAME_LEN_SIZE];
@@ -3365,7 +3442,7 @@
dec->fix_buffer_pointer();
buf2[0]= (char)(dec->intg + dec->frac);
buf2[1]= (char)dec->frac;
- decimal2bin((decimal*)val, buf2+2, buf2[0], buf2[1]);
+ decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
break;
}
@@ -3390,6 +3467,7 @@
my_b_safe_write(file, (byte*) buf1, buf1_length) ||
my_b_safe_write(file, (byte*) pos, val_len));
}
+#endif
/*
@@ -3432,8 +3510,8 @@
int str_len= sizeof(str_buf) - 1;
int precision= (int)val[0];
int scale= (int)val[1];
- decimal_digit dec_buf[10];
- decimal dec;
+ decimal_digit_t dec_buf[10];
+ decimal_t dec;
dec.len= 10;
dec.buf= dec_buf;
@@ -3663,6 +3741,7 @@
}
+#ifndef MYSQL_CLIENT
bool Slave_log_event::write(IO_CACHE* file)
{
ulong event_length= get_data_size();
@@ -3673,6 +3752,7 @@
return (write_header(file, event_length) ||
my_b_safe_write(file, (byte*) mem_pool, event_length));
}
+#endif
void Slave_log_event::init_from_mem_pool(int data_size)
@@ -3799,7 +3879,6 @@
sql_ex.force_new_format();
DBUG_VOID_RETURN;
}
-#endif /* !MYSQL_CLIENT */
/*
@@ -3844,6 +3923,7 @@
return res;
}
+#endif /* !MYSQL_CLIENT */
/*
Create_file_log_event ctor
@@ -3976,8 +4056,10 @@
strmov(p, ".info"); // strmov takes less code than memcpy
strnmov(proc_info, "Making temp file ", 17); // no end 0
thd->proc_info= proc_info;
- if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC,
- MYF(MY_WME))) < 0 ||
+ my_delete(fname_buf, MYF(0)); // old copy may exist already
+ if ((fd= my_create(fname_buf, CREATE_MODE,
+ O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
+ MYF(MY_WME))) < 0 ||
init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
MYF(MY_WME|MY_NABP)))
{
@@ -4001,8 +4083,10 @@
my_close(fd, MYF(0));
// fname_buf now already has .data, not .info, because we did our trick
- if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC,
- MYF(MY_WME))) < 0)
+ my_delete(fname_buf, MYF(0)); // old copy may exist already
+ if ((fd= my_create(fname_buf, CREATE_MODE,
+ O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
+ MYF(MY_WME))) < 0)
{
slave_print_error(rli,my_errno, "Error in Create_file event: could not open file
'%s'", fname_buf);
goto err;
@@ -4071,6 +4155,7 @@
Append_block_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Append_block_log_event::write(IO_CACHE* file)
{
byte buf[APPEND_BLOCK_HEADER_LEN];
@@ -4079,6 +4164,7 @@
my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
my_b_safe_write(file, (byte*) block, block_len));
}
+#endif
/*
@@ -4116,12 +4202,12 @@
/*
- Append_block_log_event::get_open_mode()
+ Append_block_log_event::get_create_or_append()
*/
-int Append_block_log_event::get_open_mode() const
+int Append_block_log_event::get_create_or_append() const
{
- return O_WRONLY | O_APPEND | O_BINARY;
+ return 0; /* append to the file, fail if not exists */
}
/*
@@ -4139,7 +4225,21 @@
memcpy(p, ".data", 6);
strnmov(proc_info, "Making temp file ", 17); // no end 0
thd->proc_info= proc_info;
- if ((fd = my_open(fname, get_open_mode(), MYF(MY_WME))) < 0)
+ if (get_create_or_append())
+ {
+ my_delete(fname, MYF(0)); // old copy may exist already
+ if ((fd= my_create(fname, CREATE_MODE,
+ O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
+ MYF(MY_WME))) < 0)
+ {
+ slave_print_error(rli, my_errno,
+ "Error in %s event: could not create file '%s'",
+ get_type_str(), fname);
+ goto err;
+ }
+ }
+ else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
+ MYF(MY_WME))) < 0)
{
slave_print_error(rli, my_errno,
"Error in %s event: could not open file '%s'",
@@ -4200,6 +4300,7 @@
Delete_file_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Delete_file_log_event::write(IO_CACHE* file)
{
byte buf[DELETE_FILE_HEADER_LEN];
@@ -4207,6 +4308,7 @@
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
+#endif
/*
@@ -4294,6 +4396,7 @@
Execute_load_log_event::write()
*/
+#ifndef MYSQL_CLIENT
bool Execute_load_log_event::write(IO_CACHE* file)
{
byte buf[EXEC_LOAD_HEADER_LEN];
@@ -4301,6 +4404,7 @@
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
+#endif
/*
@@ -4348,7 +4452,8 @@
Load_log_event* lev = 0;
memcpy(p, ".info", 6);
- if ((fd = my_open(fname, O_RDONLY|O_BINARY, MYF(MY_WME))) < 0 ||
+ if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
+ MYF(MY_WME))) < 0 ||
init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
MYF(MY_WME|MY_NABP)))
{
@@ -4447,9 +4552,9 @@
#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int Begin_load_query_log_event::get_open_mode() const
+int Begin_load_query_log_event::get_create_or_append() const
{
- return O_CREAT | O_WRONLY | O_BINARY | O_TRUNC;
+ return 1; /* create the file */
}
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@@ -4504,6 +4609,7 @@
}
+#ifndef MYSQL_CLIENT
bool
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
{
@@ -4514,6 +4620,7 @@
*(buf + 4 + 4 + 4)= (char)dup_handling;
return my_b_safe_write(file, (byte*) buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
}
+#endif
#ifdef MYSQL_CLIENT
@@ -4624,7 +4731,12 @@
/* Forging file name for deletion in same buffer */
*fname_end= 0;
- (void) my_delete(fname, MYF(MY_WME));
+ /*
+ If there was an error the slave is going to stop, leave the
+ file so that we can re-execute this event at START SLAVE.
+ */
+ if (!error)
+ (void) my_delete(fname, MYF(MY_WME));
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
return error;
--- 1.109/sql/log_event.h 2005-04-01 13:32:29 +02:00
+++ 1.110/sql/log_event.h 2005-04-08 11:24:24 +02:00
@@ -243,9 +243,24 @@
/* these are codes, not offsets; not more than 256 values (1 byte). */
#define Q_FLAGS2_CODE 0
#define Q_SQL_MODE_CODE 1
+#ifndef TO_BE_DELETED
+/*
+ Q_CATALOG_CODE is catalog with end zero stored; it is used only by MySQL
+ 5.0.x where 0<=x<=3.
+*/
#define Q_CATALOG_CODE 2
+#endif
#define Q_AUTO_INCREMENT 3
#define Q_CHARSET_CODE 4
+#define Q_TIME_ZONE_CODE 5
+/*
+ Q_CATALOG_NZ_CODE is catalog withOUT end zero stored; it is used by MySQL
+ 5.0.x where x>=4. Saves one byte in every Query_log_event in binlog,
+ compared to Q_CATALOG_CODE. The reason we didn't simply re-use
+ Q_CATALOG_CODE is that then a 5.0.3 slave of this 5.0.x (x>=4) master would
+ crash (segfault etc) because it would expect a 0 when there is none.
+*/
+#define Q_CATALOG_NZ_CODE 6
/* Intvar event post-header */
@@ -468,6 +483,7 @@
ulong auto_increment_increment, auto_increment_offset;
bool charset_inited;
char charset[6]; // 3 variables, each of them storable in 2 bytes
+ char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
st_last_event_info()
:flags2_inited(0), sql_mode_inited(0),
auto_increment_increment(1),auto_increment_offset(1), charset_inited(0)
@@ -479,6 +495,7 @@
*/
bzero(db, sizeof(db));
bzero(charset, sizeof(charset));
+ bzero(time_zone_str, sizeof(time_zone_str));
}
} LAST_EVENT_INFO;
#endif
@@ -603,6 +620,7 @@
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
+#ifndef MYSQL_CLIENT
bool write_header(IO_CACHE* file, ulong data_length);
virtual bool write(IO_CACHE* file)
{
@@ -610,13 +628,14 @@
write_data_header(file) ||
write_data_body(file));
}
- virtual bool is_artificial_event() { return 0; }
virtual bool write_data_header(IO_CACHE* file)
{ return 0; }
virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
{ return 0; }
+#endif
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0;
+ virtual bool is_artificial_event() { return 0; }
inline bool get_cache_stmt() { return cache_stmt; }
Log_event(const char* buf, const Format_description_log_event* description_event);
virtual ~Log_event() { free_temp_buf();}
@@ -744,7 +763,7 @@
concerned) from here.
*/
- int catalog_len; // <= 255 char; -1 means uninited
+ uint catalog_len; // <= 255 char; 0 means uninited
/*
We want to be able to store a variable number of N-bit status vars:
@@ -786,6 +805,8 @@
ulong sql_mode;
ulong auto_increment_increment, auto_increment_offset;
char charset[6];
+ uint time_zone_len; /* 0 means uninited */
+ const char *time_zone_str;
#ifndef MYSQL_CLIENT
@@ -809,12 +830,13 @@
~Query_log_event()
{
if (data_buf)
- {
my_free((gptr) data_buf, MYF(0));
- }
}
Log_event_type get_type_code() { return QUERY_EVENT; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+ virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
+#endif
bool is_valid() const { return query != 0; }
/*
@@ -823,7 +845,6 @@
*/
virtual ulong get_post_header_size_for_derived() { return 0; }
/* Writes derived event-specific part of post header. */
- virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
};
#ifdef HAVE_REPLICATION
@@ -862,7 +883,9 @@
int get_data_size();
bool is_valid() const { return master_host != 0; }
Log_event_type get_type_code() { return SLAVE_EVENT; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
};
#endif /* HAVE_REPLICATION */
@@ -957,8 +980,10 @@
{
return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
}
+#ifndef MYSQL_CLIENT
bool write_data_header(IO_CACHE* file);
bool write_data_body(IO_CACHE* file);
+#endif
bool is_valid() const { return table_name != 0; }
int get_data_size()
{
@@ -1034,7 +1059,9 @@
const Format_description_log_event* description_event);
~Start_log_event_v3() {}
Log_event_type get_type_code() { return START_EVENT_V3;}
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
int get_data_size()
{
@@ -1076,7 +1103,9 @@
const Format_description_log_event* description_event);
~Format_description_log_event() { my_free((gptr)post_header_len, MYF(0)); }
Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const
{
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
@@ -1126,7 +1155,9 @@
Log_event_type get_type_code() { return INTVAR_EVENT;}
const char* get_var_type_name();
int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;}
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
};
@@ -1164,7 +1195,9 @@
~Rand_log_event() {}
Log_event_type get_type_code() { return RAND_EVENT;}
int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
};
@@ -1199,7 +1232,9 @@
~Xid_log_event() {}
Log_event_type get_type_code() { return XID_EVENT;}
int get_data_size() { return sizeof(xid); }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
};
@@ -1241,7 +1276,9 @@
User_var_log_event(const char* buf, const Format_description_log_event*
description_event);
~User_var_log_event() {}
Log_event_type get_type_code() { return USER_VAR_EVENT;}
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
bool is_valid() const { return 1; }
};
@@ -1311,7 +1348,9 @@
Log_event_type get_type_code() { return ROTATE_EVENT;}
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
bool is_valid() const { return new_log_ident != 0; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
};
@@ -1371,6 +1410,7 @@
4 + 1 + block_len);
}
bool is_valid() const { return inited_from_old || block != 0; }
+#ifndef MYSQL_CLIENT
bool write_data_header(IO_CACHE* file);
bool write_data_body(IO_CACHE* file);
/*
@@ -1378,6 +1418,7 @@
write it as Load event - used on the slave
*/
bool write_base(IO_CACHE* file);
+#endif
};
@@ -1412,7 +1453,7 @@
#ifdef HAVE_REPLICATION
int exec_event(struct st_relay_log_info* rli);
void pack_info(Protocol* protocol);
- virtual int get_open_mode() const;
+ virtual int get_create_or_append() const;
#endif /* HAVE_REPLICATION */
#else
void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
@@ -1424,7 +1465,9 @@
Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
bool is_valid() const { return block != 0; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
const char* get_db() { return db; }
};
@@ -1458,7 +1501,9 @@
Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
bool is_valid() const { return file_id != 0; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
const char* get_db() { return db; }
};
@@ -1491,7 +1536,9 @@
Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
bool is_valid() const { return file_id != 0; }
+#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
+#endif
const char* get_db() { return db; }
};
@@ -1514,7 +1561,7 @@
bool using_trans);
#ifdef HAVE_REPLICATION
Begin_load_query_log_event(THD* thd);
- int get_open_mode() const;
+ int get_create_or_append() const;
#endif /* HAVE_REPLICATION */
#endif
Begin_load_query_log_event(const char* buf, uint event_len,
@@ -1579,7 +1626,9 @@
bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; }
ulong get_post_header_size_for_derived();
+#ifndef MYSQL_CLIENT
bool write_post_header_for_derived(IO_CACHE* file);
+#endif
};
--- 1.284/sql/mysql_priv.h 2005-04-01 22:17:23 +02:00
+++ 1.285/sql/mysql_priv.h 2005-04-08 11:24:24 +02:00
@@ -1076,6 +1076,8 @@
extern ulong query_buff_size, thread_stack,thread_stack_min;
extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
extern ulong max_binlog_size, max_relay_log_size;
+extern my_bool opt_binlog_row_level;
+extern ulong opt_binlog_row_event_max_size;
extern ulong rpl_recovery_rank, thread_cache_size;
extern ulong back_log;
extern ulong specialflag, current_pid;
--- 1.445/sql/mysqld.cc 2005-04-05 05:26:15 +02:00
+++ 1.446/sql/mysqld.cc 2005-04-08 11:24:24 +02:00
@@ -19,6 +19,7 @@
#include <my_dir.h>
#include "slave.h"
#include "sql_repl.h"
+#include "rpl_filter.h"
#include "repl_failsafe.h"
#include "stacktrace.h"
#include "mysqld_suffix.h"
@@ -400,12 +401,10 @@
FILE *bootstrap_file;
int bootstrap_error;
-I_List<i_string_pair> replicate_rewrite_db;
-I_List<i_string> replicate_do_db, replicate_ignore_db;
-// allow the user to tell us which db to replicate and which to ignore
-I_List<i_string> binlog_do_db, binlog_ignore_db;
I_List<THD> threads,thread_cache;
I_List<NAMED_LIST> key_caches;
+Rpl_filter* rpl_filter;
+Rpl_filter* binlog_filter;
struct system_variables global_system_variables;
struct system_variables max_system_variables;
@@ -423,6 +422,7 @@
SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_query_cache;
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
SHOW_COMP_OPTION have_crypt, have_compress;
+SHOW_COMP_OPTION have_blackhole_db;
/* Thread specific variables */
@@ -1016,12 +1016,9 @@
free_max_user_conn();
#ifdef HAVE_REPLICATION
end_slave_list();
- free_list(&replicate_do_db);
- free_list(&replicate_ignore_db);
- free_list(&binlog_do_db);
- free_list(&binlog_ignore_db);
- free_list(&replicate_rewrite_db);
#endif
+ delete binlog_filter;
+ delete rpl_filter;
#ifdef HAVE_OPENSSL
if (ssl_acceptor_fd)
my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR));
@@ -2973,9 +2970,16 @@
int main(int argc, char **argv)
#endif
{
-
DEBUGGER_OFF;
+ rpl_filter= new Rpl_filter;
+ binlog_filter= new Rpl_filter;
+ if (!rpl_filter || !binlog_filter)
+ {
+ sql_perror("Could not allocate replication and binlog filters");
+ exit(1);
+ }
+
MY_INIT(argv[0]); // init my_sys library & pthreads
#ifdef _CUSTOMSTARTUPCONFIG_
@@ -3137,8 +3141,17 @@
#endif
if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
opt_skip_slave_start= 1;
- /* init_slave() must be called after the thread keys are created */
- init_slave();
+ /*
+ init_slave() must be called after the thread keys are created.
+ Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
+ places) assume that active_mi != 0, so let's fail if it's 0 (out of
+ memory); a message has already been printed.
+ */
+ if (init_slave() && !active_mi)
+ {
+ end_thr_alarm(1); // Don't allow alarms
+ unireg_abort(1);
+ }
if (opt_bootstrap)
{
@@ -3312,10 +3325,10 @@
int main(int argc, char **argv)
{
-
- /* When several instances are running on the same machine, we
- need to have an unique named hEventShudown through the
- application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
+ /*
+ When several instances are running on the same machine, we
+ need to have an unique named hEventShudown through the
+ application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
*/
int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
"MySQLShutdown"), 10);
@@ -3894,10 +3907,19 @@
char *suffix_pos;
char connect_number_char[22], *p;
const char *errmsg= 0;
+ SECURITY_ATTRIBUTES *sa_event= 0, *sa_mapping= 0;
my_thread_init();
DBUG_ENTER("handle_connections_shared_memorys");
DBUG_PRINT("general",("Waiting for allocated shared memory."));
+ if (my_security_attr_create(&sa_event, &errmsg,
+ GENERIC_ALL, SYNCHRONIZE | EVENT_MODIFY_STATE))
+ goto error;
+
+ if (my_security_attr_create(&sa_mapping, &errmsg,
+ GENERIC_ALL, FILE_MAP_READ | FILE_MAP_WRITE))
+ goto error;
+
/*
The name of event and file-mapping events create agree next rule:
shared_memory_base_name+unique_part
@@ -3907,22 +3929,22 @@
*/
suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
strmov(suffix_pos, "CONNECT_REQUEST");
- if ((smem_event_connect_request= CreateEvent(0,FALSE,FALSE,tmp)) == 0)
+ if ((smem_event_connect_request= CreateEvent(sa_event,
+ FALSE, FALSE, tmp)) == 0)
{
errmsg= "Could not create request event";
goto error;
}
strmov(suffix_pos, "CONNECT_ANSWER");
- if ((event_connect_answer= CreateEvent(0,FALSE,FALSE,tmp)) == 0)
+ if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
{
errmsg="Could not create answer event";
goto error;
}
strmov(suffix_pos, "CONNECT_DATA");
- if ((handle_connect_file_map= CreateFileMapping(INVALID_HANDLE_VALUE,0,
- PAGE_READWRITE,
- 0,sizeof(connect_number),
- tmp)) == 0)
+ if ((handle_connect_file_map=
+ CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
+ PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0)
{
errmsg= "Could not create file mapping";
goto error;
@@ -3967,10 +3989,9 @@
suffix_pos= strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
"_",NullS);
strmov(suffix_pos, "DATA");
- if ((handle_client_file_map= CreateFileMapping(INVALID_HANDLE_VALUE,0,
- PAGE_READWRITE,0,
- smem_buffer_length,
- tmp)) == 0)
+ if ((handle_client_file_map=
+ CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
+ PAGE_READWRITE, 0, smem_buffer_length, tmp)) == 0)
{
errmsg= "Could not create file mapping";
goto errorconn;
@@ -3983,31 +4004,33 @@
goto errorconn;
}
strmov(suffix_pos, "CLIENT_WROTE");
- if ((event_client_wrote= CreateEvent(0, FALSE, FALSE, tmp)) == 0)
+ if ((event_client_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
{
errmsg= "Could not create client write event";
goto errorconn;
}
strmov(suffix_pos, "CLIENT_READ");
- if ((event_client_read= CreateEvent(0, FALSE, FALSE, tmp)) == 0)
+ if ((event_client_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
{
errmsg= "Could not create client read event";
goto errorconn;
}
strmov(suffix_pos, "SERVER_READ");
- if ((event_server_read= CreateEvent(0, FALSE, FALSE, tmp)) == 0)
+ if ((event_server_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
{
errmsg= "Could not create server read event";
goto errorconn;
}
strmov(suffix_pos, "SERVER_WROTE");
- if ((event_server_wrote= CreateEvent(0, FALSE, FALSE, tmp)) == 0)
+ if ((event_server_wrote= CreateEvent(sa_event,
+ FALSE, FALSE, tmp)) == 0)
{
errmsg= "Could not create server write event";
goto errorconn;
}
strmov(suffix_pos, "CONNECTION_CLOSED");
- if ((event_conn_closed= CreateEvent(0, TRUE , FALSE, tmp)) == 0)
+ if ((event_conn_closed= CreateEvent(sa_event,
+ TRUE, FALSE, tmp)) == 0)
{
errmsg= "Could not create closed connection event";
goto errorconn;
@@ -4082,6 +4105,8 @@
strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
sql_perror(buff);
}
+ my_security_attr_free(sa_event);
+ my_security_attr_free(sa_mapping);
if (handle_connect_map) UnmapViewOfFile(handle_connect_map);
if (handle_connect_file_map) CloseHandle(handle_connect_file_map);
if (event_connect_answer) CloseHandle(event_connect_answer);
@@ -5243,7 +5268,7 @@
"Max number of errors/warnings to store for a statement.",
(gptr*) &global_system_variables.max_error_count,
(gptr*) &max_system_variables.max_error_count,
- 0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 1, 65535, 0, 1, 0},
+ 0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
{"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
"Don't allow creation of heap tables bigger than this.",
(gptr*) &global_system_variables.max_heap_table_size,
@@ -5707,7 +5732,8 @@
{"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count),
SHOW_LONG_STATUS},
{"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count),
SHOW_LONG_STATUS},
{"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
- {"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
+ {"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
+ {"Slave_retried_transactions",(char*) 0,
SHOW_SLAVE_RETRIED_TRANS},
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
{"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count),
SHOW_LONG_STATUS},
{"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes),
SHOW_LONG_STATUS},
@@ -5901,13 +5927,6 @@
exit(1);
multi_keycache_init(); /* set key_cache_hash.default_value = dflt_key_cache */
- /* Initialize structures that is used when processing options */
- replicate_rewrite_db.empty();
- replicate_do_db.empty();
- replicate_ignore_db.empty();
- binlog_do_db.empty();
- binlog_ignore_db.empty();
-
/* Set directory paths */
strmake(language, LANGUAGE, sizeof(language)-1);
strmake(mysql_real_data_home, get_relative_path(DATADIR),
@@ -5972,6 +5991,11 @@
#else
have_archive_db= SHOW_OPTION_NO;
#endif
+#ifdef HAVE_BLACKHOLE_DB
+ have_blackhole_db= SHOW_OPTION_YES;
+#else
+ have_blackhole_db= SHOW_OPTION_NO;
+#endif
#ifdef HAVE_FEDERATED_DB
have_federated_db= SHOW_OPTION_YES;
#else
@@ -6162,14 +6186,12 @@
}
case (int)OPT_REPLICATE_IGNORE_DB:
{
- i_string *db = new i_string(argument);
- replicate_ignore_db.push_back(db);
+ rpl_filter->add_ignore_db(argument);
break;
}
case (int)OPT_REPLICATE_DO_DB:
{
- i_string *db = new i_string(argument);
- replicate_do_db.push_back(db);
+ rpl_filter->add_do_db(argument);
break;
}
case (int)OPT_REPLICATE_REWRITE_DB:
@@ -6202,15 +6224,13 @@
exit(1);
}
- i_string_pair *db_pair = new i_string_pair(key, val);
- replicate_rewrite_db.push_back(db_pair);
+ rpl_filter->add_db_rewrite(key, val);
break;
}
case (int)OPT_BINLOG_IGNORE_DB:
{
- i_string *db = new i_string(argument);
- binlog_ignore_db.push_back(db);
+ binlog_filter->add_ignore_db(argument);
break;
}
case OPT_BINLOG_FORMAT:
@@ -6235,58 +6255,43 @@
case (int)OPT_BINLOG_DO_DB:
{
- i_string *db = new i_string(argument);
- binlog_do_db.push_back(db);
+ binlog_filter->add_do_db(argument);
break;
}
case (int)OPT_REPLICATE_DO_TABLE:
{
- if (!do_table_inited)
- init_table_rule_hash(&replicate_do_table, &do_table_inited);
- if (add_table_rule(&replicate_do_table, argument))
+ if (rpl_filter->add_do_table(argument))
{
fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
exit(1);
}
- table_rules_on = 1;
break;
}
case (int)OPT_REPLICATE_WILD_DO_TABLE:
{
- if (!wild_do_table_inited)
- init_table_rule_array(&replicate_wild_do_table,
- &wild_do_table_inited);
- if (add_wild_table_rule(&replicate_wild_do_table, argument))
+ if (rpl_filter->add_wild_do_table(argument))
{
fprintf(stderr, "Could not add do table rule '%s'!\n", argument);
exit(1);
}
- table_rules_on = 1;
break;
}
case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
{
- if (!wild_ignore_table_inited)
- init_table_rule_array(&replicate_wild_ignore_table,
- &wild_ignore_table_inited);
- if (add_wild_table_rule(&replicate_wild_ignore_table, argument))
+ if (rpl_filter->add_wild_ignore_table(argument))
{
fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
exit(1);
}
- table_rules_on = 1;
break;
}
case (int)OPT_REPLICATE_IGNORE_TABLE:
{
- if (!ignore_table_inited)
- init_table_rule_hash(&replicate_ignore_table, &ignore_table_inited);
- if (add_table_rule(&replicate_ignore_table, argument))
+ if (rpl_filter->add_ignore_table(argument))
{
fprintf(stderr, "Could not add ignore table rule '%s'!\n", argument);
exit(1);
}
- table_rules_on = 1;
break;
}
#endif /* HAVE_REPLICATION */
--- 1.243/sql/slave.cc 2005-04-01 13:32:30 +02:00
+++ 1.244/sql/slave.cc 2005-04-08 11:24:25 +02:00
@@ -22,12 +22,14 @@
#include <myisam.h>
#include "slave.h"
#include "sql_repl.h"
+#include "rpl_filter.h"
#include "repl_failsafe.h"
#include <thr_alarm.h>
#include <my_dir.h>
#include <sql_common.h>
#include "rpl_tblmap.h"
+#define MAX_SLAVE_RETRY_PAUSE 5
bool use_slave_mask = 0;
MY_BITMAP slave_error_mask;
@@ -36,11 +38,7 @@
volatile bool slave_sql_running = 0, slave_io_running = 0;
char* slave_load_tmpdir = 0;
MASTER_INFO *active_mi;
-HASH replicate_do_table, replicate_ignore_table;
-DYNAMIC_ARRAY replicate_wild_do_table, replicate_wild_ignore_table;
-bool do_table_inited = 0, ignore_table_inited = 0;
-bool wild_do_table_inited = 0, wild_ignore_table_inited = 0;
-bool table_rules_on= 0, replicate_same_server_id;
+bool replicate_same_server_id;
ulonglong relay_log_space_limit = 0;
/*
@@ -194,20 +192,6 @@
}
-static void free_table_ent(TABLE_RULE_ENT* e)
-{
- my_free((gptr) e, MYF(0));
-}
-
-
-static byte* get_table_key(TABLE_RULE_ENT* e, uint* len,
- my_bool not_used __attribute__((unused)))
-{
- *len = e->key_len;
- return (byte*)e->db;
-}
-
-
/*
Open the given relay log
@@ -809,228 +793,6 @@
}
-void init_table_rule_hash(HASH* h, bool* h_inited)
-{
- hash_init(h, system_charset_info,TABLE_RULE_HASH_SIZE,0,0,
- (hash_get_key) get_table_key,
- (hash_free_key) free_table_ent, 0);
- *h_inited = 1;
-}
-
-
-void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited)
-{
- my_init_dynamic_array(a, sizeof(TABLE_RULE_ENT*), TABLE_RULE_ARR_SIZE,
- TABLE_RULE_ARR_SIZE);
- *a_inited = 1;
-}
-
-
-static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len)
-{
- uint i;
- const char* key_end = key + len;
-
- for (i = 0; i < a->elements; i++)
- {
- TABLE_RULE_ENT* e ;
- get_dynamic(a, (gptr)&e, i);
- if (!my_wildcmp(system_charset_info, key, key_end,
- (const char*)e->db,
- (const char*)(e->db + e->key_len),
- '\\',wild_one,wild_many))
- return e;
- }
-
- return 0;
-}
-
-
-/*
- Checks whether tables match some (wild_)do_table and (wild_)ignore_table
- rules (for replication)
-
- SYNOPSIS
- tables_ok()
- thd thread (SQL slave thread normally)
- tables list of tables to check
-
- NOTES
- Note that changing the order of the tables in the list can lead to
- different results. Note also the order of precedence of the do/ignore
- rules (see code below). For that reason, users should not set conflicting
- rules because they may get unpredicted results (precedence order is
- explained in the manual).
- If no table of the list is marked "updating" (so far this can only happen
- if the statement is a multi-delete (SQLCOM_DELETE_MULTI) and the "tables"
- is the tables in the FROM): then we always return 0, because there is no
- reason we play this statement on this slave if it updates nothing. In the
- case of SQLCOM_DELETE_MULTI, there will be a second call to tables_ok(),
- with tables having "updating==TRUE" (those after the DELETE), so this
- second call will make the decision (because
- all_tables_not_ok() = !tables_ok(1st_list) && !tables_ok(2nd_list)).
-
- Thought which arose from a question of a big customer "I want to include
- all tables like "abc.%" except the "%.EFG"". This can't be done now. If we
- supported Perl regexps we could do it with this pattern: /^abc\.(?!EFG)/
- (I could not find an equivalent in the regex library MySQL uses).
-
- RETURN VALUES
- 0 should not be logged/replicated
- 1 should be logged/replicated
-*/
-
-bool tables_ok(THD* thd, TABLE_LIST* tables)
-{
- bool some_tables_updating= 0;
- DBUG_ENTER("tables_ok");
-
- for (; tables; tables= tables->next_global)
- {
- char hash_key[2*NAME_LEN+2];
- char *end;
- uint len;
-
- if (!tables->updating)
- continue;
- some_tables_updating= 1;
- end= strmov(hash_key, tables->db ? tables->db : thd->db);
- *end++= '.';
- len= (uint) (strmov(end, tables->table_name) - hash_key);
- if (do_table_inited) // if there are any do's
- {
- if (hash_search(&replicate_do_table, (byte*) hash_key, len))
- DBUG_RETURN(1);
- }
- if (ignore_table_inited) // if there are any ignores
- {
- if (hash_search(&replicate_ignore_table, (byte*) hash_key, len))
- DBUG_RETURN(0);
- }
- if (wild_do_table_inited && find_wild(&replicate_wild_do_table,
- hash_key, len))
- DBUG_RETURN(1);
- if (wild_ignore_table_inited && find_wild(&replicate_wild_ignore_table,
- hash_key, len))
- DBUG_RETURN(0);
- }
-
- /*
- If no table was to be updated, ignore statement (no reason we play it on
- slave, slave is supposed to replicate _changes_ only).
- If no explicit rule found and there was a do list, do not replicate.
- If there was no do list, go ahead
- */
- DBUG_RETURN(some_tables_updating &&
- !do_table_inited && !wild_do_table_inited);
-}
-
-
-/*
- Checks whether a db matches wild_do_table and wild_ignore_table
- rules (for replication)
-
- SYNOPSIS
- db_ok_with_wild_table()
- db name of the db to check.
- Is tested with check_db_name() before calling this function.
-
- NOTES
- Here is the reason for this function.
- We advise users who want to exclude a database 'db1' safely to do it
- with replicate_wild_ignore_table='db1.%' instead of binlog_ignore_db or
- replicate_ignore_db because the two lasts only check for the selected db,
- which won't work in that case:
- USE db2;
- UPDATE db1.t SET ... #this will be replicated and should not
- whereas replicate_wild_ignore_table will work in all cases.
- With replicate_wild_ignore_table, we only check tables. When
- one does 'DROP DATABASE db1', tables are not involved and the
- statement will be replicated, while users could expect it would not (as it
- rougly means 'DROP db1.first_table, DROP db1.second_table...').
- In other words, we want to interpret 'db1.%' as "everything touching db1".
- That is why we want to match 'db1' against 'db1.%' wild table rules.
-
- RETURN VALUES
- 0 should not be logged/replicated
- 1 should be logged/replicated
- */
-
-int db_ok_with_wild_table(const char *db)
-{
- char hash_key[NAME_LEN+2];
- char *end;
- int len;
- end= strmov(hash_key, db);
- *end++= '.';
- len= end - hash_key ;
- if (wild_do_table_inited && find_wild(&replicate_wild_do_table,
- hash_key, len))
- return 1;
- if (wild_ignore_table_inited && find_wild(&replicate_wild_ignore_table,
- hash_key, len))
- return 0;
-
- /*
- If no explicit rule found and there was a do list, do not replicate.
- If there was no do list, go ahead
- */
- return !wild_do_table_inited;
-}
-
-
-int add_table_rule(HASH* h, const char* table_spec)
-{
- const char* dot = strchr(table_spec, '.');
- if (!dot) return 1;
- // len is always > 0 because we know the there exists a '.'
- uint len = (uint)strlen(table_spec);
- TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
- + len, MYF(MY_WME));
- if (!e) return 1;
- e->db = (char*)e + sizeof(TABLE_RULE_ENT);
- e->tbl_name = e->db + (dot - table_spec) + 1;
- e->key_len = len;
- memcpy(e->db, table_spec, len);
- (void)my_hash_insert(h, (byte*)e);
- return 0;
-}
-
-
-/*
- Add table expression with wildcards to dynamic array
-*/
-
-int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
-{
- const char* dot = strchr(table_spec, '.');
- if (!dot) return 1;
- uint len = (uint)strlen(table_spec);
- TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
- + len, MYF(MY_WME));
- if (!e) return 1;
- e->db = (char*)e + sizeof(TABLE_RULE_ENT);
- e->tbl_name = e->db + (dot - table_spec) + 1;
- e->key_len = len;
- memcpy(e->db, table_spec, len);
- insert_dynamic(a, (gptr)&e);
- return 0;
-}
-
-
-static void free_string_array(DYNAMIC_ARRAY *a)
-{
- uint i;
- for (i = 0; i < a->elements; i++)
- {
- char* p;
- get_dynamic(a, (gptr) &p, i);
- my_free(p, MYF(MY_WME));
- }
- delete_dynamic(a);
-}
-
-
#ifdef NOT_USED_YET
static int end_slave_on_walk(MASTER_INFO* mi, gptr /*unused*/)
{
@@ -1066,14 +828,6 @@
*/
terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
end_master_info(active_mi);
- if (do_table_inited)
- hash_free(&replicate_do_table);
- if (ignore_table_inited)
- hash_free(&replicate_ignore_table);
- if (wild_do_table_inited)
- free_string_array(&replicate_wild_do_table);
- if (wild_ignore_table_inited)
- free_string_array(&replicate_wild_ignore_table);
delete active_mi;
active_mi= 0;
}
@@ -1153,24 +907,6 @@
}
-const char *rewrite_db(const char* db, uint32 *new_len)
-{
- if (replicate_rewrite_db.is_empty() || !db)
- return db;
- I_List_iterator<i_string_pair> it(replicate_rewrite_db);
- i_string_pair* tmp;
-
- while ((tmp=it++))
- {
- if (!strcmp(tmp->key, db))
- {
- *new_len= (uint32)strlen(tmp->val);
- return tmp->val;
- }
- }
- return db;
-}
-
/*
From other comments and tests in code, it looks like
sometimes Query_log_event and Load_log_event can have db == 0
@@ -1183,60 +919,6 @@
return (db ? db : "");
}
-/*
- Checks whether a db matches some do_db and ignore_db rules
- (for logging or replication)
-
- SYNOPSIS
- db_ok()
- db name of the db to check
- do_list either binlog_do_db or replicate_do_db
- ignore_list either binlog_ignore_db or replicate_ignore_db
-
- RETURN VALUES
- 0 should not be logged/replicated
- 1 should be logged/replicated
-*/
-
-int db_ok(const char* db, I_List<i_string> &do_list,
- I_List<i_string> &ignore_list )
-{
- if (do_list.is_empty() && ignore_list.is_empty())
- return 1; // ok to replicate if the user puts no constraints
-
- /*
- If the user has specified restrictions on which databases to replicate
- and db was not selected, do not replicate.
- */
- if (!db)
- return 0;
-
- if (!do_list.is_empty()) // if the do's are not empty
- {
- I_List_iterator<i_string> it(do_list);
- i_string* tmp;
-
- while ((tmp=it++))
- {
- if (!strcmp(tmp->ptr, db))
- return 1; // match
- }
- return 0;
- }
- else // there are some elements in the don't, otherwise we cannot get here
- {
- I_List_iterator<i_string> it(ignore_list);
- i_string* tmp;
-
- while ((tmp=it++))
- {
- if (!strcmp(tmp->ptr, db))
- return 0; // match
- }
- return 1;
- }
-}
-
static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
const char *default_val)
@@ -1457,11 +1139,10 @@
such check will broke everything for them. (And now everything will
work for them because by default both their master and slave will have
'SYSTEM' time zone).
-
- TODO: when the new replication of timezones is sorted out with Dmitri,
- change >= '4' to == '4'.
+ This check is only necessary for 4.x masters (and < 5.0.4 masters but
+ those were alpha).
*/
- if ((*mysql->server_version >= '4') &&
+ if ((*mysql->server_version == '4') &&
!mysql_real_query(mysql, "SELECT @@GLOBAL.TIME_ZONE", 25) &&
(master_res= mysql_store_result(mysql)))
{
@@ -2246,48 +1927,6 @@
}
-/*
- Builds a String from a HASH of TABLE_RULE_ENT. Cannot be used for any other
- hash, as it assumes that the hash entries are TABLE_RULE_ENT.
-
- SYNOPSIS
- table_rule_ent_hash_to_str()
- s pointer to the String to fill
- h pointer to the HASH to read
-
- RETURN VALUES
- none
-*/
-
-void table_rule_ent_hash_to_str(String* s, HASH* h)
-{
- s->length(0);
- for (uint i=0 ; i < h->records ; i++)
- {
- TABLE_RULE_ENT* e= (TABLE_RULE_ENT*) hash_element(h, i);
- if (s->length())
- s->append(',');
- s->append(e->db,e->key_len);
- }
-}
-
-/*
- Mostly the same thing as above
-*/
-
-void table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a)
-{
- s->length(0);
- for (uint i=0 ; i < a->elements ; i++)
- {
- TABLE_RULE_ENT* e;
- get_dynamic(a, (gptr)&e, i);
- if (s->length())
- s->append(',');
- s->append(e->db,e->key_len);
- }
-}
-
bool show_master_info(THD* thd, MASTER_INFO* mi)
{
// TODO: fix this for multi-master
@@ -2382,23 +2021,18 @@
protocol->store(mi->rli.group_master_log_name, &my_charset_bin);
protocol->store(mi->slave_running ? "Yes":"No", &my_charset_bin);
protocol->store(mi->rli.slave_running ? "Yes":"No", &my_charset_bin);
- protocol->store(&replicate_do_db);
- protocol->store(&replicate_ignore_db);
- /*
- We can't directly use some protocol->store for
- replicate_*_table,
- as Protocol doesn't know the TABLE_RULE_ENT struct.
- We first build Strings and then pass them to protocol->store.
- */
+ protocol->store(rpl_filter->get_do_db());
+ protocol->store(rpl_filter->get_ignore_db());
+
char buf[256];
String tmp(buf, sizeof(buf), &my_charset_bin);
- table_rule_ent_hash_to_str(&tmp, &replicate_do_table);
+ rpl_filter->get_do_table(&tmp);
protocol->store(&tmp);
- table_rule_ent_hash_to_str(&tmp, &replicate_ignore_table);
+ rpl_filter->get_ignore_table(&tmp);
protocol->store(&tmp);
- table_rule_ent_dynamic_array_to_str(&tmp, &replicate_wild_do_table);
+ rpl_filter->get_wild_do_table(&tmp);
protocol->store(&tmp);
- table_rule_ent_dynamic_array_to_str(&tmp, &replicate_wild_ignore_table);
+ rpl_filter->get_wild_ignore_table(&tmp);
protocol->store(&tmp);
protocol->store((uint32) mi->rli.last_slave_errno);
@@ -2530,7 +2164,7 @@
ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0),
abort_pos_wait(0), slave_run_id(0), sql_thd(0), last_slave_errno(0),
inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE),
- until_log_pos(0)
+ until_log_pos(0), retried_trans(0)
{
group_relay_log_name[0]= event_relay_log_name[0]=
group_master_log_name[0]= 0;
@@ -2770,6 +2404,18 @@
thd->variables.completion_type= 0;
}
+void set_slave_thread_default_charset(THD* thd, RELAY_LOG_INFO *rli)
+{
+ thd->variables.character_set_client=
+ global_system_variables.character_set_client;
+ thd->variables.collation_connection=
+ global_system_variables.collation_connection;
+ thd->variables.collation_server=
+ global_system_variables.collation_server;
+ thd->update_charset();
+ rli->cached_charset_invalidate();
+}
+
/*
init_slave_thread()
*/
@@ -3250,9 +2896,8 @@
init_master_info()).
b) init_relay_log_pos(), because the BEGIN may be an older relay log.
*/
- if (rli->trans_retries--)
+ if (rli->trans_retries < slave_trans_retries)
{
- sql_print_information("Slave SQL thread retries transaction");
if (init_master_info(rli->mi, 0, 0, 0, SLAVE_SQL))
sql_print_error("Failed to initialize the master info structure");
else if (init_relay_log_pos(rli,
@@ -3264,8 +2909,16 @@
else
{
exec_res= 0;
- sleep(2); // chance for concurrent connection to get more locks
- }
+ /* chance for concurrent connection to get more locks */
+ safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
+ rli->trans_retries++;
+ rli->retried_trans++;
+ pthread_mutex_unlock(&rli->data_lock);
+ DBUG_PRINT("info", ("Slave retries transaction "
+ "rli->trans_retries: %lu", rli->trans_retries));
+ }
}
else
sql_print_error("Slave SQL thread retried transaction %lu time(s) "
@@ -3274,8 +2927,8 @@
slave_trans_retries);
}
if (!((thd->options & OPTION_BEGIN) && opt_using_transactions))
- rli->trans_retries= slave_trans_retries; // restart from fresh
- }
+ rli->trans_retries= 0; // restart from fresh
+ }
return exec_res;
}
else
@@ -3690,7 +3343,7 @@
pthread_mutex_lock(&rli->log_space_lock);
rli->ignore_log_space_limit= 0;
pthread_mutex_unlock(&rli->log_space_lock);
- rli->trans_retries= slave_trans_retries; // start from "no error"
+ rli->trans_retries= 0; // start from "no error"
if (init_relay_log_pos(rli,
rli->group_relay_log_name,
@@ -3845,10 +3498,8 @@
if (unlikely(!cev->is_valid()))
DBUG_RETURN(1);
- /*
- TODO: fix to honor table rules, not only db rules
- */
- if (!db_ok(cev->db, replicate_do_db, replicate_ignore_db))
+
+ if (!rpl_filter->db_ok(cev->db))
{
skip_load_data_infile(net);
DBUG_RETURN(0);
--- 1.135/sql/sql_acl.cc 2005-04-01 13:32:31 +02:00
+++ 1.136/sql/sql_acl.cc 2005-04-08 11:24:25 +02:00
@@ -27,9 +27,6 @@
#include "mysql_priv.h"
#include "hash_filo.h"
-#ifdef HAVE_REPLICATION
-#include "sql_repl.h" //for tables_ok()
-#endif
#include <m_ctype.h>
#include <stdarg.h>
#include "sp_head.h"
@@ -241,7 +238,7 @@
DBUG_PRINT("info",("user table fields: %d, password length: %d",
table->s->fields, table->field[2]->field_length));
-
+
pthread_mutex_lock(&LOCK_global_system_variables);
if (table->field[2]->field_length < SCRAMBLED_PASSWORD_CHAR_LENGTH)
{
@@ -325,6 +322,12 @@
if (table->s->fields <= 33 && (user.access & ALTER_ACL))
user.access|= ALTER_PROC_ACL;
+ /*
+ pre 5.0.3 did not have CREATE_USER_ACL
+ */
+ if (table->s->fields <= 36 && (user.access & GRANT_ACL))
+ user.access|= CREATE_USER_ACL;
+
user.sort= get_sort(2,user.host.hostname,user.user);
user.hostname_length= (user.host.hostname ?
(uint) strlen(user.host.hostname) : 0);
@@ -1093,6 +1096,9 @@
/*
Get privilege for a host, user and db combination
+
+ as db_is_pattern changes the semantics of comparison,
+ acl_cache is not used if db_is_pattern is set.
*/
ulong acl_get(const char *host, const char *ip,
@@ -1112,7 +1118,7 @@
db=tmp_db;
}
key_length=(uint) (end-key);
- if ((entry=(acl_entry*) acl_cache->search(key,key_length)))
+ if (!db_is_pattern && (entry=(acl_entry*)
acl_cache->search(key,key_length)))
{
db_access=entry->access;
VOID(pthread_mutex_unlock(&acl_cache->lock));
@@ -1161,7 +1167,8 @@
}
exit:
/* Save entry in cache for quick retrieval */
- if ((entry= (acl_entry*) malloc(sizeof(acl_entry)+key_length)))
+ if (!db_is_pattern &&
+ (entry= (acl_entry*) malloc(sizeof(acl_entry)+key_length)))
{
entry->access=(db_access & host_access);
entry->length=key_length;
@@ -1499,7 +1506,7 @@
GRANT and REVOKE are applied the slave in/exclusion rules as they are
some kind of updates to the mysql.% tables.
*/
- if (thd->slave_thread && table_rules_on)
+ if (thd->slave_thread && rpl_filter->is_on())
{
/*
The tables must be marked "updating" so that tables_ok() takes them into
@@ -1507,7 +1514,7 @@
*/
tables.updating= 1;
/* Thanks to bzero, tables.next==0 */
- if (!tables_ok(0, &tables))
+ if (!rpl_filter->tables_ok(0, &tables))
DBUG_RETURN(0);
}
#endif
@@ -1543,18 +1550,26 @@
}
-/* Return 1 if we are allowed to create new users */
+/*
+ Return 1 if we are allowed to create new users
+ the logic here is: INSERT_ACL is sufficient.
+ It's also a requirement in opt_safe_user_create,
+ otherwise CREATE_USER_ACL is enough.
+*/
static bool test_if_create_new_users(THD *thd)
{
- bool create_new_users=1; // Assume that we are allowed to create new users
- if (opt_safe_user_create && !(thd->master_access & INSERT_ACL))
+ bool create_new_users= test(thd->master_access & INSERT_ACL) ||
+ (!opt_safe_user_create &&
+ test(thd->master_access & CREATE_USER_ACL));
+ if (!create_new_users)
{
TABLE_LIST tl;
ulong db_access;
bzero((char*) &tl,sizeof(tl));
tl.db= (char*) "mysql";
tl.table_name= (char*) "user";
+ create_new_users= 1;
db_access=acl_get(thd->host, thd->ip,
thd->priv_user, tl.db, 0);
@@ -1574,7 +1589,7 @@
static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
ulong rights, bool revoke_grant,
- bool create_user)
+ bool can_create_user, bool no_auto_create)
{
int error = -1;
bool old_row_exists=0;
@@ -1616,8 +1631,8 @@
goto end;
}
/*
- There are four options which affect the process of creation of
- a new user(mysqld option --safe-create-user, 'insert' privilege
+ There are four options which affect the process of creation of
+ a new user (mysqld option --safe-create-user, 'insert' privilege
on 'mysql.user' table, using 'GRANT' with 'IDENTIFIED BY' and
SQL_MODE flag NO_AUTO_CREATE_USER). Below is the simplified rule
how it should work.
@@ -1625,11 +1640,17 @@
else if (identified_by) => create
else if (no_auto_create_user) => reject
else create
+
+ see also test_if_create_new_users()
*/
- else if (((thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER) &&
- !password_len) || !create_user)
+ else if (!password_len && no_auto_create)
{
- my_error(ER_NO_PERMISSION_TO_CREATE_USER, MYF(0),
+ my_error(ER_PASSWORD_NO_MATCH, MYF(0), combo.user.str, combo.host.str);
+ goto end;
+ }
+ else if (!can_create_user)
+ {
+ my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0),
thd->user, thd->host_or_ip);
goto end;
}
@@ -2670,14 +2691,14 @@
GRANT and REVOKE are applied the slave in/exclusion rules as they are
some kind of updates to the mysql.% tables.
*/
- if (thd->slave_thread && table_rules_on)
+ if (thd->slave_thread && rpl_filter->is_on())
{
/*
The tables must be marked "updating" so that tables_ok() takes them into
account in tests.
*/
tables[0].updating= tables[1].updating= tables[2].updating= 1;
- if (!tables_ok(0, tables))
+ if (!rpl_filter->tables_ok(0, tables))
DBUG_RETURN(FALSE);
}
#endif
@@ -2710,7 +2731,9 @@
/* Create user if needed */
pthread_mutex_lock(&acl_cache->lock);
error=replace_user_table(thd, tables[0].table, *Str,
- 0, revoke_grant, create_new_users);
+ 0, revoke_grant, create_new_users,
+ test(thd->variables.sql_mode &
+ MODE_NO_AUTO_CREATE_USER));
pthread_mutex_unlock(&acl_cache->lock);
if (error)
{
@@ -2873,14 +2896,14 @@
GRANT and REVOKE are applied the slave in/exclusion rules as they are
some kind of updates to the mysql.% tables.
*/
- if (thd->slave_thread && table_rules_on)
+ if (thd->slave_thread && rpl_filter->is_on())
{
/*
The tables must be marked "updating" so that tables_ok() takes them into
account in tests.
*/
tables[0].updating= tables[1].updating= 1;
- if (!tables_ok(0, tables))
+ if (!rpl_filter->tables_ok(0, tables))
DBUG_RETURN(FALSE);
}
#endif
@@ -2915,7 +2938,9 @@
/* Create user if needed */
pthread_mutex_lock(&acl_cache->lock);
error=replace_user_table(thd, tables[0].table, *Str,
- 0, revoke_grant, create_new_users);
+ 0, revoke_grant, create_new_users,
+ test(thd->variables.sql_mode &
+ MODE_NO_AUTO_CREATE_USER));
pthread_mutex_unlock(&acl_cache->lock);
if (error)
{
@@ -2927,7 +2952,7 @@
table_name= table_list->table_name;
grant_name= proc_hash_search(Str->host.str, NullS, db_name,
- Str->user.str, table_name, 1);
+ Str->user.str, table_name, 1);
if (!grant_name)
{
if (revoke_grant)
@@ -2948,7 +2973,7 @@
}
my_hash_insert(&proc_priv_hash,(byte*) grant_name);
}
-
+
if (replace_proc_table(thd, grant_name, tables[1].table, *Str,
db_name, table_name, rights, revoke_grant))
{
@@ -3002,14 +3027,14 @@
GRANT and REVOKE are applied the slave in/exclusion rules as they are
some kind of updates to the mysql.% tables.
*/
- if (thd->slave_thread && table_rules_on)
+ if (thd->slave_thread && rpl_filter->is_on())
{
/*
The tables must be marked "updating" so that tables_ok() takes them into
account in tests.
*/
tables[0].updating= tables[1].updating= 1;
- if (!tables_ok(0, tables))
+ if (!rpl_filter->tables_ok(0, tables))
DBUG_RETURN(FALSE);
}
#endif
@@ -3039,11 +3064,10 @@
result= -1;
continue;
}
- if ((replace_user_table(thd,
- tables[0].table,
- *Str,
- (!db ? rights : 0), revoke_grant,
- create_new_users)))
+ if (replace_user_table(thd, tables[0].table, *Str,
+ (!db ? rights : 0), revoke_grant, create_new_users,
+ test(thd->variables.sql_mode &
+ MODE_NO_AUTO_CREATE_USER)))
result= -1;
else if (db)
{
@@ -3690,11 +3714,13 @@
"ALTER", "SHOW DATABASES", "SUPER", "CREATE TEMPORARY TABLES",
"LOCK TABLES", "EXECUTE", "REPLICATION SLAVE", "REPLICATION CLIENT",
"CREATE VIEW", "SHOW VIEW", "CREATE ROUTINE", "ALTER ROUTINE",
+ "CREATE USER"
};
static uint command_lengths[]=
{
- 6, 6, 6, 6, 6, 4, 6, 8, 7, 4, 5, 10, 5, 5, 14, 5, 23, 11, 7, 17, 18, 11, 9, 14, 13
+ 6, 6, 6, 6, 6, 4, 6, 8, 7, 4, 5, 10, 5, 5, 14, 5, 23, 11, 7, 17, 18, 11, 9,
+ 14, 13, 11
};
@@ -4210,7 +4236,7 @@
GRANT and REVOKE are applied the slave in/exclusion rules as they are
some kind of updates to the mysql.% tables.
*/
- if (thd->slave_thread && table_rules_on)
+ if (thd->slave_thread && rpl_filter->is_on())
{
/*
The tables must be marked "updating" so that tables_ok() takes them into
@@ -4218,7 +4244,7 @@
*/
tables[0].updating=tables[1].updating=tables[2].updating=
tables[3].updating=tables[4].updating=1;
- if (!tables_ok(0, tables))
+ if (!rpl_filter->tables_ok(0, tables))
DBUG_RETURN(1);
tables[0].updating=tables[1].updating=tables[2].updating=
tables[3].updating=tables[4].updating=0;;
@@ -4810,13 +4836,11 @@
}
sql_mode= thd->variables.sql_mode;
- thd->variables.sql_mode&= ~MODE_NO_AUTO_CREATE_USER;
- if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1))
+ if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1, 0))
{
append_user(&wrong_users, user_name);
result= TRUE;
}
- thd->variables.sql_mode= sql_mode;
}
VOID(pthread_mutex_unlock(&acl_cache->lock));
@@ -4972,7 +4996,7 @@
}
if (replace_user_table(thd, tables[0].table,
- *lex_user, ~0, 1, 0))
+ *lex_user, ~0, 1, 0, 0))
{
result= -1;
continue;
--- 1.34/sql/sql_acl.h 2005-03-21 22:12:10 +01:00
+++ 1.35/sql/sql_acl.h 2005-04-08 11:24:25 +02:00
@@ -14,6 +14,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#include "slave.h" // for tables_ok(), rpl_filter
+
#define SELECT_ACL (1L << 0)
#define INSERT_ACL (1L << 1)
#define UPDATE_ACL (1L << 2)
@@ -39,12 +41,17 @@
#define SHOW_VIEW_ACL (1L << 22)
#define CREATE_PROC_ACL (1L << 23)
#define ALTER_PROC_ACL (1L << 24)
+#define CREATE_USER_ACL (1L << 25)
/*
don't forget to update
- static struct show_privileges_st sys_privileges[]
- in sql_show.cc when adding new privileges!
+ 1. static struct show_privileges_st sys_privileges[]
+ 2. static const char *command_array[] and static uint command_lengths[]
+ 3. mysql_create_system_tables.sh, mysql_fix_privilege_tables.sql
+ 4. acl_init() or whatever - to define behaviour for old privilege tables
+ 5. sql_yacc.yy - for GRANT/REVOKE to work
*/
-
+#define EXTRA_ACL (1L << 29)
+#define NO_ACCESS (1L << 30)
#define DB_ACLS \
(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | \
@@ -71,10 +78,7 @@
REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \
CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \
EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | \
- ALTER_PROC_ACL )
-
-#define EXTRA_ACL (1L << 29)
-#define NO_ACCESS (1L << 30)
+ ALTER_PROC_ACL | CREATE_USER_ACL)
#define DEFAULT_CREATE_PROC_ACLS \
(ALTER_PROC_ACL | EXECUTE_ACL)
@@ -84,25 +88,21 @@
This is needed as the 'host' and 'db' table is missing a few privileges
*/
-/* Continius bit-segments that needs to be shifted */
-#define DB_REL1 ((1L << 6) | (1L << 7) | (1L << 8) | (1L << 9))
-#define DB_REL2 ((1L << 10) | (1L << 11))
-#define DB_REL3 ((1L << 12) | (1L << 13) | (1L << 14) | (1L <<
15))
-#define DB_REL4 ((1L << 16))
-
/* Privileges that needs to be reallocated (in continous chunks) */
+#define DB_CHUNK0 (SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | \
+ CREATE_ACL | DROP_ACL)
#define DB_CHUNK1 (GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL)
#define DB_CHUNK2 (CREATE_TMP_ACL | LOCK_TABLES_ACL)
#define DB_CHUNK3 (CREATE_VIEW_ACL | SHOW_VIEW_ACL | \
CREATE_PROC_ACL | ALTER_PROC_ACL )
#define DB_CHUNK4 (EXECUTE_ACL)
-#define fix_rights_for_db(A) (((A) & 63) | \
- (((A) & DB_REL1) << 4) | \
- (((A) & DB_REL2) << 6) | \
- (((A) & DB_REL3) << 9) | \
- (((A) & DB_REL4) << 2))
-#define get_rights_for_db(A) (((A) & 63) | \
+#define fix_rights_for_db(A) (((A) & DB_CHUNK0) | \
+ (((A) << 4) & DB_CHUNK1) | \
+ (((A) << 6) & DB_CHUNK2) | \
+ (((A) << 9) & DB_CHUNK3) | \
+ (((A) << 2) & DB_CHUNK4))
+#define get_rights_for_db(A) (((A) & DB_CHUNK0) | \
(((A) & DB_CHUNK1) >> 4) | \
(((A) & DB_CHUNK2) >> 6) | \
(((A) & DB_CHUNK3) >> 9) | \
@@ -189,8 +189,7 @@
bool mysql_procedure_grant(THD *thd, TABLE_LIST *table,
List <LEX_USER> &user_list, ulong rights,
bool revoke, bool no_error);
-ACL_USER *check_acl_user(LEX_USER *user_name,
- uint *acl_acl_userdx);
+ACL_USER *check_acl_user(LEX_USER *user_name, uint *acl_acl_userdx);
my_bool grant_init(THD *thd);
void grant_free(void);
void grant_reload(THD *thd);
--- 1.174/sql/sql_class.cc 2005-04-01 13:40:13 +02:00
+++ 1.175/sql/sql_class.cc 2005-04-08 11:24:25 +02:00
@@ -193,6 +193,7 @@
variables.pseudo_thread_id= 0;
one_shot_set= 0;
file_id = 0;
+ query_id= 0;
warn_id= 0;
db_charset= global_system_variables.collation_database;
bzero(ha_data, sizeof(ha_data));
--- 1.228/sql/sql_class.h 2005-04-01 22:17:27 +02:00
+++ 1.229/sql/sql_class.h 2005-04-08 11:24:25 +02:00
@@ -23,12 +23,15 @@
// TODO: create log.h and move all the log header stuff there
+#include "rpl_tblmap.h"
+
class Query_log_event;
class Load_log_event;
class Slave_log_event;
class Format_description_log_event;
class sp_rcontext;
class sp_cache;
+class Rows_log_event;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
@@ -54,6 +57,9 @@
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
extern uint tc_heuristic_recover;
+// Forward declaration
+class THD;
+
/*
Transaction Coordinator log - a base abstract class
for two different implementations
@@ -234,6 +240,11 @@
pthread_cond_t COND_prep_xids;
friend class Log_event;
+ // 'Mutable' needed since this class can not be initialized in the
+ // constructor.
+ mutable table_mapping* m_table_map;
+ ulong m_next_table_id;
+
public:
MYSQL_LOG();
/*
@@ -248,6 +259,18 @@
void unlog(ulong cookie, my_xid xid);
int recover(IO_CACHE *log, Format_description_log_event *fdle);
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ // This will return a table id for the table. If the table is not known, a
+ // new table id will be invented and returned.
+ ulong get_table_id(TABLE* table);
+
+ // This will check if the given table is mapped to any table id
+ int is_table_mapped(TABLE* table) const;
+
+ // This will clear all table mappings
+ void clear_table_mappings();
+
+#endif // !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
/*
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
@@ -1078,6 +1101,51 @@
my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */
/* container for handler's private per-connection data */
void *ha_data[MAX_HA];
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+
+ /*
+ Public interface to write rows to the binlog
+ */
+ int write_row(TABLE* table, bitvector const& cols, const byte *buf);
+ int delete_row(TABLE* table, bitvector const& cols, const byte *buf);
+ int update_row(TABLE* table, bitvector const& cols,
+ const byte *old_data, const byte *new_data);
+
+ void set_server_id(uint32 sid) { server_id = sid; }
+
+ int transaction_begin() {
+ return 0;
+ }
+
+ int transaction_end() {
+
+ return flush_pending_event(true);
+ }
+
+private:
+ /*
+ Member functions to handle pending event for row-level logging.
+ */
+ Rows_log_event* get_pending_event() const;
+ int set_pending_event(Rows_log_event* ev);
+ int flush_and_set_pending_event(Rows_log_event*);
+
+ template <class RowsEventT>
+ Rows_log_event*
+ prepare_pending(TABLE* table, uint32 server_id,
+ bitvector const& cols, size_t needed);
+
+ size_t max_row_length(TABLE* table, const byte *data) const;
+ size_t pack_row(TABLE* table, byte *row_data,
+ size_t max_len, const byte *data) const;
+
+ int flush_pending_event(bool stmt_end);
+ int write_table_map(TABLE*);
+
+#endif
+
+public:
struct st_transactions {
SAVEPOINT *savepoints;
THD_TRANS all; // Trans since BEGIN WORK
@@ -1085,6 +1153,9 @@
bool on; // see ha_enable_transaction()
XID xid; // transaction identifier
enum xa_states xa_state; // used by external XA only
+
+ Rows_log_event* m_pending_rows_event;
+
/*
Tables changed in transaction (that must be invalidated in query cache).
List contain only transactional tables, that not invalidated in query
--- 1.145/sql/sql_insert.cc 2005-03-19 01:12:22 +01:00
+++ 1.146/sql/sql_insert.cc 2005-04-08 11:24:25 +02:00
@@ -313,6 +313,8 @@
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)));
+ table->file->ha_stmt_begin();
+
if (fields.elements && check_that_all_fields_are_given_values(thd, table))
{
/* thd->net.report_error is now set, which will abort the next loop */
@@ -404,6 +406,8 @@
table->triggers->process_triggers(thd, TRG_EVENT_INSERT, TRG_ACTION_AFTER);
}
+ table->file->ha_stmt_end();
+
/*
Now all rows are inserted. Time to update logs and sends response to
user
@@ -447,7 +451,7 @@
if ((info.copied || info.deleted || info.updated) &&
(error <= 0 || !transactional_table))
{
- if (mysql_bin_log.is_open())
+ if (!opt_binlog_row_level && mysql_bin_log.is_open())
{
if (error <= 0)
thd->clear_error();
@@ -743,10 +747,11 @@
DBUG_ENTER("write_record");
info->records++;
+
if (info->handle_duplicates == DUP_REPLACE ||
info->handle_duplicates == DUP_UPDATE)
{
- while ((error=table->file->write_row(table->record[0])))
+ while ((error=table->file->ha_write_row(table->record[0])))
{
uint key_nr;
if (error != HA_WRITE_SKIP)
@@ -820,7 +825,7 @@
if (res == VIEW_CHECK_ERROR)
goto err;
- if
((error=table->file->update_row(table->record[1],table->record[0])))
+ if
((error=table->file->ha_update_row(table->record[1],table->record[0])))
goto err;
info->updated++;
break;
@@ -840,13 +845,13 @@
(table->timestamp_field_type == TIMESTAMP_NO_AUTO_SET ||
table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH))
{
- if ((error=table->file->update_row(table->record[1],
- table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],
+ table->record[0])))
goto err;
info->deleted++;
break; /* Update logfile and count */
}
- else if ((error=table->file->delete_row(table->record[1])))
+ else if ((error=table->file->ha_delete_row(table->record[1])))
goto err;
info->deleted++;
if (!table->file->has_transactions())
@@ -855,7 +860,7 @@
}
info->copied++;
}
- else if ((error=table->file->write_row(table->record[0])))
+ else if ((error=table->file->ha_write_row(table->record[0])))
{
if (!info->ignore ||
(error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE))
--- 1.229/sql/sql_table.cc 2005-03-23 09:32:42 +01:00
+++ 1.230/sql/sql_table.cc 2005-04-08 11:24:26 +02:00
@@ -187,6 +187,29 @@
bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
DBUG_ENTER("mysql_rm_table_part2");
+#ifdef USE_PREPARE_CODE
+ for (table= tables; table; table= table->next_local)
+ {
+ if (!drop_temporary)
+ {
+ char *db=table->db;
+ alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
+ /* remove form file and isam files */
+ strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS);
+ (void) unpack_filename(path,path);
+ db_type table_type= get_table_type(path);
+ char *end;
+ *(end=fn_ext(path))=0; // Remove extension for delete
+
+ TABLE dummy_table;
+ TABLE_SHARE dummy_share;
+ dummy_table.s= &dummy_share;
+ handler *file=get_new_handler(&dummy_table, table_type);
+ file->prepare_delete_table(path);
+ }
+ }
+#endif
+
if (lock_table_names(thd, tables))
DBUG_RETURN(1);
@@ -3749,7 +3772,7 @@
{
copy_ptr->do_copy(copy_ptr);
}
- if ((error=to->file->write_row((byte*) to->record[0])))
+ if ((error=to->file->ha_write_row((byte*) to->record[0])))
{
if ((!ignore &&
handle_duplicates != DUP_REPLACE) ||
--- 1.152/sql/sql_update.cc 2005-04-01 13:32:33 +02:00
+++ 1.153/sql/sql_update.cc 2005-04-08 11:24:26 +02:00
@@ -29,7 +29,7 @@
/* Return 0 if row hasn't changed */
-static bool compare_record(TABLE *table, ulong query_id)
+static bool compare_record(TABLE *table, query_id_t query_id)
{
if (table->s->blob_fields + table->s->varchar_fields == 0)
return cmp_record(table,record[1]);
@@ -125,7 +125,7 @@
uint want_privilege;
#endif
uint table_count= 0;
- ulong query_id=thd->query_id, timestamp_query_id;
+ query_id_t query_id=thd->query_id, timestamp_query_id;
ha_rows updated, found;
key_map old_used_keys;
TABLE *table;
--- 1.114/sql/sql_union.cc 2005-03-21 19:24:56 +01:00
+++ 1.115/sql/sql_union.cc 2005-04-08 11:24:26 +02:00
@@ -30,7 +30,7 @@
DBUG_ENTER("mysql_union");
bool res;
if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK |
- setup_tables_done_option)))
+ setup_tables_done_option, "")))
res= unit->exec();
if (!res && thd->cursor && thd->cursor->is_open())
{
@@ -140,7 +140,8 @@
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
- ulong additional_options)
+ ulong additional_options,
+ const char *tmp_table_alias)
{
SELECT_LEX *lex_select_save= thd_arg->lex->current_select;
SELECT_LEX *sl, *first_select;
@@ -255,7 +256,7 @@
while ((item_tmp= it++))
{
/* Error's in 'new' will be detected after loop */
- types.push_back(new Item_type_holder(thd_arg, item_tmp, empty_table));
+ types.push_back(new Item_type_holder(thd_arg, item_tmp));
}
if (thd_arg->is_fatal_error)
@@ -274,8 +275,7 @@
Item *type, *item_tmp;
while ((type= tp++, item_tmp= it++))
{
- if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp,
- empty_table))
+ if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
DBUG_RETURN(TRUE);
}
}
@@ -308,7 +308,7 @@
(first_select_in_union()->options |
thd_arg->options |
TMP_TABLE_ALL_COLUMNS),
- HA_POS_ERROR, (char*) "")))
+ HA_POS_ERROR, (char *) tmp_table_alias)))
goto err;
table->file->extra(HA_EXTRA_WRITE_CACHE);
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
@@ -418,7 +418,7 @@
}
/* re-enabling indexes for next subselect iteration */
if (union_distinct && table->file->enable_indexes(HA_KEY_SWITCH_ALL))
- DBUG_ASSERT(TRUE);
+ DBUG_ASSERT(0);
}
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{
--- 1.35/mysql-test/r/ctype_ucs.result 2005-04-01 13:40:12 +02:00
+++ 1.36/mysql-test/r/ctype_ucs.result 2005-04-08 11:24:22 +02:00
@@ -642,3 +642,11 @@
Warning 1264 Out of range value adjusted for column 'Field1' at row 1
DROP TABLE t1;
SET NAMES latin1;
+CREATE TABLE t1 (a varchar(64) character set ucs2, b decimal(10,3));
+INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0);
+update t1 set b=a;
+SELECT * FROM t1;
+a b
+1.1 1.100
+2.1 2.100
+DROP TABLE t1;
--- 1.28/mysql-test/t/ctype_ucs.test 2005-04-01 13:32:24 +02:00
+++ 1.29/mysql-test/t/ctype_ucs.test 2005-04-08 11:24:23 +02:00
@@ -414,3 +414,12 @@
INSERT INTO t1 VALUES ('-1');
DROP TABLE t1;
SET NAMES latin1;
+
+#
+# Conversion from an UCS2 string to a decimal column
+#
+CREATE TABLE t1 (a varchar(64) character set ucs2, b decimal(10,3));
+INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0);
+update t1 set b=a;
+SELECT * FROM t1;
+DROP TABLE t1;
--- 1.281/BitKeeper/etc/logging_ok 2005-03-21 22:11:48 +01:00
+++ 1.282/BitKeeper/etc/logging_ok 2005-04-08 11:24:14 +02:00
@@ -25,6 +25,7 @@
bar@stripped
bar@stripped
bar@deer.(none)
+bar@stripped
bar@stripped
bar@stripped
bar@stripped
@@ -48,6 +49,7 @@
dlenev@stripped
dlenev@stripped
ejonore@stripped
+gbichot@stripped
gbichot@stripped
gbichot@stripped
georg@stripped
@@ -118,6 +120,7 @@
lars@stripped
lenz@stripped
lenz@stripped
+magnus@stripped
magnus@neptunus.(none)
magnus@shellback.(none)
marko@stripped
@@ -186,6 +189,7 @@
patg@krsna.
patg@stripped
patg@stripped
+patg@stripped
patg@stripped
paul@stripped
paul@stripped
@@ -226,6 +230,7 @@
sasha@stripped
serg@stripped
serg@stripped
+serg@stripped
serg@stripped
serg@stripped
serg@stripped
--- 1.12/mysql-test/r/rpl_timezone.result 2005-04-01 13:32:23 +02:00
+++ 1.13/mysql-test/r/rpl_timezone.result 2005-04-08 11:24:22 +02:00
@@ -4,21 +4,31 @@
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
+set timestamp=100000000;
create table t1 (t timestamp);
create table t2 (t char(32));
select @@time_zone;
@@time_zone
+Japan
+select @@time_zone;
+@@time_zone
Europe/Moscow
+insert into t1 values ('20050101000000'), ('20050611093902');
set time_zone='UTC';
insert into t1 values ('20040101000000'), ('20040611093902');
select * from t1;
t
+2004-12-31 21:00:00
+2005-06-11 05:39:02
2004-01-01 00:00:00
2004-06-11 09:39:02
+set time_zone='UTC';
select * from t1;
t
-2004-01-01 03:00:00
-2004-06-11 13:39:02
+2004-12-31 21:00:00
+2005-06-11 05:39:02
+2004-01-01 00:00:00
+2004-06-11 09:39:02
delete from t1;
set time_zone='Europe/Moscow';
insert into t1 values ('20040101000000'), ('20040611093902');
@@ -26,19 +36,51 @@
t
2004-01-01 00:00:00
2004-06-11 09:39:02
+set time_zone='Europe/Moscow';
+select * from t1;
+t
+2004-01-01 00:00:00
+2004-06-11 09:39:02
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ROLLBACK;
+use test;
+SET TIMESTAMP=100000000;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1,
@@session.unique_checks=1;
+SET @@session.sql_mode=0;
+SET
@@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
+create table t1 (t timestamp);
+SET TIMESTAMP=100000000;
+create table t2 (t char(32));
+SET TIMESTAMP=100000000;
+SET @@session.time_zone='Europe/Moscow';
+insert into t1 values ('20050101000000'), ('20050611093902');
+SET TIMESTAMP=100000000;
+SET @@session.time_zone='UTC';
+insert into t1 values ('20040101000000'), ('20040611093902');
+SET TIMESTAMP=100000000;
+delete from t1;
+SET TIMESTAMP=100000000;
+SET @@session.time_zone='Europe/Moscow';
+insert into t1 values ('20040101000000'), ('20040611093902');
+ROLLBACK;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+delete from t1;
+set time_zone='UTC';
+load data infile '../../std_data/rpl_timezone.dat' into table t1;
select * from t1;
t
2004-01-01 00:00:00
2004-06-11 09:39:02
-show binlog events;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
-master-bin.000001 # Query 1 # use `test`; create table t1 (t timestamp)
-master-bin.000001 # Query 1 # use `test`; create table t2 (t char(32))
-master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT TIME_ZONE='UTC'
-master-bin.000001 # Query 1 # use `test`; insert into t1 values ('20040101000000'),
('20040611093902')
-master-bin.000001 # Query 1 # use `test`; delete from t1
-master-bin.000001 # Query 1 # use `test`; insert into t1 values ('20040101000000'),
('20040611093902')
+set time_zone='UTC';
+select * from t1;
+t
+2004-01-01 00:00:00
+2004-06-11 09:39:02
+set time_zone='Europe/Moscow';
+set time_zone='Europe/Moscow';
+delete from t1;
+insert into t1 values ('20040101000000'), ('20040611093902');
set time_zone='MET';
insert into t2 (select t from t1);
select * from t1;
@@ -52,10 +94,6 @@
delete from t2;
set timestamp=1000072000;
insert into t2 values (current_timestamp), (current_date), (current_time);
-set timestamp=1000072000;
-select current_timestamp, current_date, current_time;
-current_timestamp current_date current_time
-2001-09-10 01:46:40 2001-09-10 01:46:40
select * from t2;
t
2001-09-09 23:46:40
@@ -73,5 +111,16 @@
2001-09-09 03:46:40
1000000000
set global time_zone='MET';
-ERROR HY000: Binary logging and replication forbid changing the global server time zone
+delete from t2;
+set time_zone='UTC';
+insert into t2 values(convert_tz('2004-01-01 00:00:00','MET',@@time_zone));
+insert into t2 values(convert_tz('2005-01-01 00:00:00','MET','Japan'));
+select * from t2;
+t
+2003-12-31 23:00:00
+2005-01-01 08:00:00
+select * from t2;
+t
+2003-12-31 23:00:00
+2005-01-01 08:00:00
drop table t1, t2;
--- 1.40/mysql-test/r/information_schema.result 2005-03-21 23:26:17 +01:00
+++ 1.41/mysql-test/r/information_schema.result 2005-04-08 11:24:22 +02:00
@@ -121,8 +121,8 @@
t3
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t2 MyISAM 9 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
-t3 MyISAM 9 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
+t2 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
+t3 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL view
show full columns from t3 like "a%";
Field Type Collation Null Key Default Extra Privileges Comment
@@ -436,7 +436,6 @@
information_schema.tables;
s1
0
-9
10
drop table t1;
SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets;
@@ -446,7 +445,7 @@
`DEFAULT_COLLATE_NAME` varchar(64) NOT NULL default '',
`DESCRIPTION` varchar(60) NOT NULL default '',
`MAXLEN` bigint(3) NOT NULL default '0'
-) ENGINE=MEMORY DEFAULT CHARSET=utf8 MAX_ROWS=1818
+) ENGINE=MEMORY DEFAULT CHARSET=utf8
set names latin2;
SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets;
Table Create Table
@@ -455,7 +454,7 @@
`DEFAULT_COLLATE_NAME` varchar(64) NOT NULL default '',
`DESCRIPTION` varchar(60) NOT NULL default '',
`MAXLEN` bigint(3) NOT NULL default '0'
-) ENGINE=MEMORY DEFAULT CHARSET=utf8 MAX_ROWS=1818
+) ENGINE=MEMORY DEFAULT CHARSET=utf8
set names latin1;
create table t1 select * from information_schema.CHARACTER_SETS
where CHARACTER_SET_NAME like "latin1";
@@ -656,6 +655,8 @@
CREATE TABLE t_crashme ( f1 BIGINT);
CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
+count(*)
+100
drop view a2, a1;
drop table t_crashme;
select table_schema,table_name, column_name from
--- 1.31/mysql-test/r/ps_1general.result 2005-03-21 23:26:17 +01:00
+++ 1.32/mysql-test/r/ps_1general.result 2005-04-08 11:24:22 +02:00
@@ -291,7 +291,7 @@
prepare stmt4 from ' show table status from test like ''t2%'' ';
execute stmt4;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t2 MyISAM 9 Fixed 0 0 0 64424509439 1024 0 NULL # # # latin1_swedish_ci NULL
+t2 MyISAM 10 Fixed 0 0 0 64424509439 1024 0 NULL # # # latin1_swedish_ci NULL
prepare stmt4 from ' show table status from test like ''t9%'' ';
execute stmt4;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
@@ -343,6 +343,7 @@
ARCHIVE YES/NO Archive storage engine
CSV YES/NO CSV storage engine
FEDERATED YES/NO Federated MySQL storage engine
+BLACKHOLE YES/NO /dev/null storage engine (anything you write to it disappears)
drop table if exists t5;
prepare stmt1 from ' drop table if exists t5 ' ;
execute stmt1 ;
@@ -484,7 +485,7 @@
ERROR HY000: This command is not supported in the prepared statement protocol yet
prepare stmt1 from ' explain select a from t1 order by b ';
execute stmt1;
-Catalog Database Table Table_alias Column Column_alias Name Type Length Max
length Is_null Flags Decimals Charsetnr
+Catalog Database Table Table_alias Column Column_alias Type Length Max
length Is_null Flags Decimals Charsetnr
def id 8 3 1 N 32929 0 63
def select_type 253 19 6 N 1 31 8
def table 253 64 2 N 1 31 8
@@ -500,7 +501,7 @@
SET @arg00=1 ;
prepare stmt1 from ' explain select a from t1 where a > ? order by b ';
execute stmt1 using @arg00;
-Catalog Database Table Table_alias Column Column_alias Name Type Length Max
length Is_null Flags Decimals Charsetnr
+Catalog Database Table Table_alias Column Column_alias Type Length Max
length Is_null Flags Decimals Charsetnr
def id 8 3 1 N 32929 0 63
def select_type 253 19 6 N 1 31 8
def table 253 64 2 N 1 31 8
--- 1.43/ndb/src/kernel/blocks/dbdict/Dbdict.cpp 2005-04-06 03:20:07 +02:00
+++ 1.44/ndb/src/kernel/blocks/dbdict/Dbdict.cpp 2005-04-08 11:24:23 +02:00
@@ -2465,7 +2465,9 @@
callback.m_callbackFunction =
safe_cast(&Dbdict::restartCreateTab_dihComplete);
- SegmentedSectionPtr fragDataPtr; fragDataPtr.setNull();
+ SegmentedSectionPtr fragDataPtr;
+ fragDataPtr.sz = 0;
+ fragDataPtr.setNull();
createTab_dih(signal, createTabPtr, fragDataPtr, &callback);
}
--- 1.199/sql/ha_ndbcluster.cc 2005-04-08 13:00:30 +02:00
+++ 1.200/sql/ha_ndbcluster.cc 2005-04-08 11:24:23 +02:00
@@ -397,7 +397,7 @@
* manage uncommitted insert/deletes during transactio to get records correct
*/
-struct Ndb_table_local_info {
+struct Ndb_local_table_statistics {
int no_uncommitted_rows_count;
ulong last_count;
ha_rows records;
@@ -418,7 +418,8 @@
if (m_ha_not_exact_count)
return;
DBUG_ENTER("ha_ndbcluster::records_update");
- struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info;
+ struct Ndb_local_table_statistics *info=
+ (struct Ndb_local_table_statistics *)m_table_info;
DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d",
((const NDBTAB *)m_table)->getTableId(),
info->no_uncommitted_rows_count));
@@ -455,7 +456,8 @@
if (m_ha_not_exact_count)
return;
DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_init");
- struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info;
+ struct Ndb_local_table_statistics *info=
+ (struct Ndb_local_table_statistics *)m_table_info;
Thd_ndb *thd_ndb= get_thd_ndb(thd);
if (info->last_count != thd_ndb->count)
{
@@ -474,8 +476,8 @@
if (m_ha_not_exact_count)
return;
DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_update");
- struct Ndb_table_local_info *info=
- (struct Ndb_table_local_info *)m_table_info;
+ struct Ndb_local_table_statistics *info=
+ (struct Ndb_local_table_statistics *)m_table_info;
info->no_uncommitted_rows_count+= c;
DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d",
((const NDBTAB *)m_table)->getTableId(),
@@ -927,10 +929,8 @@
Get metadata for this table from NDB
IMPLEMENTATION
- - save the NdbDictionary::Table for easy access
- check that frm-file on disk is equal to frm-file
of table accessed in NDB
- - build a list of the indexes for the table
*/
int ha_ndbcluster::get_metadata(const char *path)
@@ -994,11 +994,12 @@
if (error)
DBUG_RETURN(error);
-
- m_table= NULL;
- m_table_info= NULL;
- DBUG_RETURN(build_index_list(table, ILBP_OPEN));
+ m_tableVersion= tab->getObjectVersion();
+ m_table= (void *)tab;
+ m_table_info= NULL; // Set in external lock
+
+ DBUG_RETURN(build_index_list(ndb, table, ILBP_OPEN));
}
static int fix_unique_index_attr_order(NDB_INDEX_DATA &data,
@@ -1026,7 +1027,7 @@
#endif
for (unsigned j= 0; j < sz; j++)
{
- const NdbDictionary::Column *c= index->getColumn(j);
+ const NDBCOL *c= index->getColumn(j);
if (strncmp(field_name, c->getName(), name_sz) == 0)
{
data.unique_index_attrid_map[i]= j;
@@ -1038,7 +1039,7 @@
DBUG_RETURN(0);
}
-int ha_ndbcluster::build_index_list(TABLE *tab, enum ILBP phase)
+int ha_ndbcluster::build_index_list(Ndb *ndb, TABLE *tab, enum ILBP phase)
{
uint i;
int error= 0;
@@ -1047,8 +1048,7 @@
static const char* unique_suffix= "$unique";
KEY* key_info= tab->key_info;
const char **key_name= tab->s->keynames.type_names;
- Ndb *ndb= get_ndb();
- NdbDictionary::Dictionary *dict= ndb->getDictionary();
+ NDBDICT *dict= ndb->getDictionary();
DBUG_ENTER("ha_ndbcluster::build_index_list");
// Save information about all known indexes
@@ -2260,6 +2260,7 @@
DBUG_ENTER("delete_row");
statistic_increment(thd->status_var.ha_delete_count,&LOCK_status);
+ m_rows_changed++;
if (cursor)
{
@@ -2310,8 +2311,6 @@
}
}
- m_rows_changed++;
-
// Execute delete operation
if (execute_no_commit(this,trans) != 0) {
no_uncommitted_rows_execute_failure();
@@ -3112,12 +3111,8 @@
}
-static const char *ha_ndb_bas_ext[]= { ha_ndb_ext, NullS };
-const char**
-ha_ndbcluster::bas_ext() const
-{
- return ha_ndb_bas_ext;
-}
+const char** ha_ndbcluster::bas_ext() const
+{ static const char *ext[]= { ha_ndb_ext, NullS }; return ext; }
/*
@@ -3196,6 +3191,10 @@
When a table lock is held one transaction will be started which holds
the table lock and for each statement a hupp transaction will be started
+ If we are locking the table then:
+ - save the NdbDictionary::Table for easy access
+ - save reference to table statistics
+ - refresh list of the indexes for the table if needed (if altered)
*/
int ha_ndbcluster::external_lock(THD *thd, int lock_type)
@@ -3301,7 +3300,15 @@
if (!(tab= dict->getTable(m_tabname, &tab_info)))
ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
- m_table= (void *)tab;
+ if (m_table != (void *)tab || m_tableVersion != tab->getObjectVersion())
+ {
+ /*
+ The table has been altered, refresh the index list
+ */
+ build_index_list(ndb, table, ILBP_OPEN);
+ m_table= (void *)tab;
+ m_tableVersion = tab->getObjectVersion();
+ }
m_table_info= tab_info;
}
no_uncommitted_rows_init(thd);
@@ -3990,7 +3997,7 @@
m_dbname, m_tabname));
// Create secondary indexes
- my_errno= build_index_list(form, ILBP_CREATE);
+ my_errno= build_index_list(ndb, form, ILBP_CREATE);
if (!my_errno)
my_errno= write_ndb_file();
@@ -4332,6 +4339,7 @@
m_active_trans(NULL),
m_active_cursor(NULL),
m_table(NULL),
+ m_tableVersion(-1),
m_table_info(NULL),
m_table_flags(HA_REC_NOT_IN_SEQ |
HA_NULL_IN_KEY |
@@ -4480,9 +4488,9 @@
DBUG_ENTER("seize_thd_ndb");
thd_ndb= new Thd_ndb();
-
thd_ndb->ndb->getDictionary()->set_local_table_data_size(sizeof(Ndb_table_local_info));
-
-
+ thd_ndb->ndb->getDictionary()->set_local_table_data_size(
+ sizeof(Ndb_local_table_statistics)
+ );
if (thd_ndb->ndb->init(max_transactions) != 0)
{
ERR_PRINT(thd_ndb->ndb->getNdbError());
@@ -4572,7 +4580,7 @@
ndb->setDatabaseName(db);
NDBDICT* dict= ndb->getDictionary();
- dict->set_local_table_data_size(sizeof(Ndb_table_local_info));
+ dict->set_local_table_data_size(sizeof(Ndb_local_table_statistics));
dict->invalidateTable(name);
if (!(tab= dict->getTable(name)))
{
@@ -4632,7 +4640,7 @@
ndb->setDatabaseName(db);
NDBDICT* dict= ndb->getDictionary();
- dict->set_local_table_data_size(sizeof(Ndb_table_local_info));
+ dict->set_local_table_data_size(sizeof(Ndb_local_table_statistics));
dict->invalidateTable(name);
if (!(tab= dict->getTable(name)))
{
@@ -4856,7 +4864,7 @@
DBUG_PRINT("error", ("failed to create global ndb object"));
goto ndbcluster_init_error;
}
- g_ndb->getDictionary()->set_local_table_data_size(sizeof(Ndb_table_local_info));
+
g_ndb->getDictionary()->set_local_table_data_size(sizeof(Ndb_local_table_statistics));
if (g_ndb->init() != 0)
{
ERR_PRINT (g_ndb->getNdbError());
--- 1.84/sql/ha_ndbcluster.h 2005-04-08 11:26:04 +02:00
+++ 1.85/sql/ha_ndbcluster.h 2005-04-08 11:24:23 +02:00
@@ -524,7 +524,7 @@
int create_unique_index(const char *name, KEY *key_info);
int initialize_autoincrement(const void *table);
enum ILBP {ILBP_CREATE = 0, ILBP_OPEN = 1}; // Index List Build Phase
- int build_index_list(TABLE *tab, enum ILBP phase);
+ int build_index_list(Ndb *ndb, TABLE *tab, enum ILBP phase);
int get_metadata(const char* path);
void release_metadata();
NDB_INDEX_TYPE get_index_type(uint idx_no) const;
@@ -609,6 +609,7 @@
NdbTransaction *m_active_trans;
NdbScanOperation *m_active_cursor;
void *m_table;
+ int m_tableVersion;
void *m_table_info;
char m_dbname[FN_HEADLEN];
//char m_schemaname[FN_HEADLEN];
--- 1.64/mysql-test/r/show_check.result 2005-03-21 23:26:18 +01:00
+++ 1.65/mysql-test/r/show_check.result 2005-04-08 11:24:23 +02:00
@@ -316,57 +316,57 @@
insert into t3 values (1,1),(2,2);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t1 MEMORY 10 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t2 MEMORY 10 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t3 MEMORY 10 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (3),(4);
insert into t2 values (3),(4);
insert into t3 values (3,3),(4,4);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t1 MEMORY 10 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t2 MEMORY 10 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t3 MEMORY 10 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t1 MEMORY 10 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t2 MEMORY 10 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t3 MEMORY 10 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=3;
delete from t2 where b=3;
delete from t3 where a=3;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
+t1 MEMORY 10 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
+t2 MEMORY 10 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
+t3 MEMORY 10 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1;
delete from t2;
delete from t3;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t1 MEMORY 10 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t2 MEMORY 10 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t3 MEMORY 10 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t1 MEMORY 10 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t2 MEMORY 10 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
+t3 MEMORY 10 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=5;
delete from t2 where b=5;
delete from t3 where a=5;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
-t1 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
-t2 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
-t3 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
+t1 MEMORY 10 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
+t2 MEMORY 10 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
+t3 MEMORY 10 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
drop table t1, t2, t3;
create database mysqltest;
show create database mysqltest;
--- 1.16/scripts/mysql_fix_privilege_tables.sql 2005-03-21 22:12:09 +01:00
+++ 1.17/scripts/mysql_fix_privilege_tables.sql 2005-04-08 11:24:23 +02:00
@@ -290,6 +290,18 @@
ALTER TABLE user ADD max_user_connections int(11) unsigned DEFAULT '0' NOT NULL AFTER
max_connections;
#
+# user.Create_user_priv
+#
+
+SET @hadCreateUserPriv:=0;
+SELECT @hadCreateUserPriv:=1 FROM user WHERE Create_user_priv LIKE '%';
+
+ALTER TABLE user ADD Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N'
NOT NULL AFTER Alter_routine_priv;
+UPDATE user LEFT JOIN db USING (Host,User) SET Create_user_priv='Y'
+ WHERE @hadCreateUserPriv = 0 AND
+ (user.Grant_priv = 'Y' OR db.Grant_priv = 'Y');
+
+#
# Create some possible missing tables
#
CREATE TABLE IF NOT EXISTS procs_priv (
@@ -306,19 +318,19 @@
CREATE TABLE IF NOT EXISTS help_topic (
help_topic_id int unsigned not null,
-name varchar(64) not null,
+name char(64) not null,
help_category_id smallint unsigned not null,
description text not null,
example text not null,
-url varchar(128) not null,
+url char(128) not null,
primary key (help_topic_id), unique index (name)
) CHARACTER SET utf8 comment='help topics';
CREATE TABLE IF NOT EXISTS help_category (
help_category_id smallint unsigned not null,
-name varchar(64) not null,
+name char(64) not null,
parent_category_id smallint unsigned null,
-url varchar(128) not null,
+url char(128) not null,
primary key (help_category_id),
unique index (name)
) CHARACTER SET utf8 comment='help categories';
@@ -331,7 +343,7 @@
CREATE TABLE IF NOT EXISTS help_keyword (
help_keyword_id int unsigned not null,
-name varchar(64) not null,
+name char(64) not null,
primary key (help_keyword_id),
unique index (name)
) CHARACTER SET utf8 comment='help keywords';
@@ -478,3 +490,35 @@
'NO_AUTO_CREATE_USER',
'HIGH_NOT_PRECEDENCE'
) DEFAULT 0 NOT NULL;
+
+#
+# Change all varchar fields in privilege tables to CHAR, to ensure that
+# we can use the privilege tables in MySQL 4.1
+# Note that for this hack to work, we must change all CHAR() columns at
+# the same time
+#
+
+ALTER TABLE mysql.user
+modify Host char(60) binary DEFAULT '' NOT NULL,
+modify User char(16) binary DEFAULT '' NOT NULL,
+modify Password char(41) binary DEFAULT '' NOT NULL;
+
+ALTER TABLE mysql.db
+modify Host char(60) binary DEFAULT '' NOT NULL,
+modify Db char(64) binary DEFAULT '' NOT NULL,
+modify User char(16) binary DEFAULT '' NOT NULL;
+
+ALTER TABLE mysql.host
+modify Host char(60) binary DEFAULT '' NOT NULL,
+modify Db char(64) binary DEFAULT '' NOT NULL;
+
+ALTER TABLE help_topic
+modify name char(64) not null,
+modify url char(128) not null;
+
+ALTER TABLE help_category
+modify name char(64) not null,
+modify url char(128) not null;
+
+ALTER TABLE help_keyword
+modify name char(64) not null;
--- 1.31/mysql-test/r/user_var.result 2005-04-01 13:32:23 +02:00
+++ 1.32/mysql-test/r/user_var.result 2005-04-08 11:24:23 +02:00
@@ -198,3 +198,10 @@
select FIELD( @var,'1it','Hit') as my_column;
my_column
0
+select @v, coercibility(@v);
+@v coercibility(@v)
+NULL 2
+set @v1=null, @v2=1, @v3=1.1, @v4=now();
+select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
+coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4)
+2 2 2 2
--- 1.25/mysql-test/t/user_var.test 2005-04-01 13:32:27 +02:00
+++ 1.26/mysql-test/t/user_var.test 2005-04-08 11:24:23 +02:00
@@ -124,3 +124,10 @@
#
set @var= NULL ;
select FIELD( @var,'1it','Hit') as my_column;
+
+#
+# Bug#9425 A user variable doesn't always have implicit coercibility
+#
+select @v, coercibility(@v);
+set @v1=null, @v2=1, @v3=1.1, @v4=now();
+select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
--- 1.21/mysql-test/r/rpl_temporary.result 2005-04-01 13:32:22 +02:00
+++ 1.22/mysql-test/r/rpl_temporary.result 2005-04-08 11:24:22 +02:00
@@ -7,12 +7,12 @@
reset master;
SET @save_select_limit=@@session.sql_select_limit;
SET @@session.sql_select_limit=10, @@session.pseudo_thread_id=100;
-ERROR HY000: Access denied; you need the SUPER privilege for this operation
+ERROR 42000: Access denied; you need the SUPER privilege for this operation
SELECT @@session.sql_select_limit = @save_select_limit;
@@session.sql_select_limit = @save_select_limit
1
SET @@session.sql_select_limit=10, @@session.sql_log_bin=0;
-ERROR HY000: Access denied; you need the SUPER privilege for this operation
+ERROR 42000: Access denied; you need the SUPER privilege for this operation
SELECT @@session.sql_select_limit = @save_select_limit;
@@session.sql_select_limit = @save_select_limit
1
--- 1.19/scripts/mysql_create_system_tables.sh 2005-04-06 16:02:49 +02:00
+++ 1.20/scripts/mysql_create_system_tables.sh 2005-04-08 11:24:23 +02:00
@@ -146,6 +146,7 @@
c_u="$c_u Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,"
c_u="$c_u Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT
NULL,"
c_u="$c_u Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT
NULL,"
+ c_u="$c_u Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT
NULL,"
c_u="$c_u ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT
'' NOT NULL,"
c_u="$c_u ssl_cipher BLOB NOT NULL,"
c_u="$c_u x509_issuer BLOB NOT NULL,"
@@ -161,22 +162,22 @@
if test "$1" = "test"
then
- i_u="INSERT INTO user VALUES
('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
- INSERT INTO user VALUES
('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
- REPLACE INTO user VALUES
('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
+ i_u="INSERT INTO user VALUES
('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
+ INSERT INTO user VALUES
('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
+ REPLACE INTO user VALUES
('127.0.0.1','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
INSERT INTO user (host,user) values ('localhost','');
INSERT INTO user (host,user) values ('$hostname','');"
else
- i_u="INSERT INTO user VALUES
('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);"
+ i_u="INSERT INTO user VALUES
('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);"
if test "$windows" = "0"
then
i_u="$i_u
- INSERT INTO user VALUES
('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
+ INSERT INTO user VALUES
('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
INSERT INTO user (host,user) values ('$hostname','');
INSERT INTO user (host,user) values ('localhost','');"
else
i_u="$i_u
- INSERT INTO user VALUES
('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);"
+ INSERT INTO user VALUES
('localhost','','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);"
fi
fi
fi
@@ -269,11 +270,11 @@
c_ht="$c_ht CREATE TABLE help_topic ("
c_ht="$c_ht help_topic_id int unsigned not null,"
- c_ht="$c_ht name varchar(64) not null,"
+ c_ht="$c_ht name char(64) not null,"
c_ht="$c_ht help_category_id smallint unsigned not null,"
c_ht="$c_ht description text not null,"
c_ht="$c_ht example text not null,"
- c_ht="$c_ht url varchar(128) not null,"
+ c_ht="$c_ht url char(128) not null,"
c_ht="$c_ht primary key (help_topic_id),"
c_ht="$c_ht unique index (name)"
c_ht="$c_ht ) engine=MyISAM"
@@ -291,9 +292,9 @@
c_hc="$c_hc CREATE TABLE help_category ("
c_hc="$c_hc help_category_id smallint unsigned not null,"
- c_hc="$c_hc name varchar(64) not null,"
+ c_hc="$c_hc name char(64) not null,"
c_hc="$c_hc parent_category_id smallint unsigned null,"
- c_hc="$c_hc url varchar(128) not null,"
+ c_hc="$c_hc url char(128) not null,"
c_hc="$c_hc primary key (help_category_id),"
c_hc="$c_hc unique index (name)"
c_hc="$c_hc ) engine=MyISAM"
@@ -309,7 +310,7 @@
c_hk="$c_hk CREATE TABLE help_keyword ("
c_hk="$c_hk help_keyword_id int unsigned not null,"
- c_hk="$c_hk name varchar(64) not null,"
+ c_hk="$c_hk name char(64) not null,"
c_hk="$c_hk primary key (help_keyword_id),"
c_hk="$c_hk unique index (name)"
c_hk="$c_hk ) engine=MyISAM"
| Thread |
|---|
| • bk commit into 5.1 tree (mysqldev:1.1854) | lars | 8 Apr |