summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authortomas@whalegate.ndb.mysql.com <>2007-12-13 14:26:57 +0100
committertomas@whalegate.ndb.mysql.com <>2007-12-13 14:26:57 +0100
commit4b5e9edd69648c899e81a348885cc0bd7ee3b503 (patch)
treea21151a99adb797108126b9e7d46f0b3f395fcf9 /storage
parent6bc455e3532fcf1494e7c2f6ccd0e1fbbcfa480c (diff)
parent8506efa91e2bccbd312411a949960ec8736a363f (diff)
downloadmariadb-git-4b5e9edd69648c899e81a348885cc0bd7ee3b503.tar.gz
Merge whalegate.ndb.mysql.com:/home/tomas/mysql-5.1
into whalegate.ndb.mysql.com:/home/tomas/mysql-5.1-new-ndb-merge
Diffstat (limited to 'storage')
-rw-r--r--storage/archive/azio.c2
-rw-r--r--storage/csv/ha_tina.cc13
-rw-r--r--storage/myisammrg/ha_myisammrg.cc31
-rw-r--r--storage/myisammrg/myrg_close.c1
-rw-r--r--storage/myisammrg/myrg_open.c17
5 files changed, 51 insertions, 13 deletions
diff --git a/storage/archive/azio.c b/storage/archive/azio.c
index 2cf0fe114d3..cada6c57918 100644
--- a/storage/archive/azio.c
+++ b/storage/archive/azio.c
@@ -262,7 +262,7 @@ void check_header(azio_stream *s)
if (len) s->inbuf[0] = s->stream.next_in[0];
errno = 0;
len = (uInt)my_read(s->file, (uchar *)s->inbuf + len, AZ_BUFSIZE_READ >> len, MYF(0));
- if (len == 0) s->z_err = Z_ERRNO;
+ if (len == (uInt)-1) s->z_err = Z_ERRNO;
s->stream.avail_in += len;
s->stream.next_in = s->inbuf;
if (s->stream.avail_in < 2) {
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index 0d9c019a19d..c9fab79a4c5 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -472,14 +472,6 @@ int ha_tina::encode_quote(uchar *buf)
const char *ptr;
const char *end_ptr;
const bool was_null= (*field)->is_null();
-
- /*
- CSV does not support nulls. ::create() prevents creation of a table
- with nullable columns so if we encounter them here, there is a bug.
- This may only occur if the frm was created by an older version of
- mysqld which permitted table creation with nullable columns.
- */
- DBUG_ASSERT(!(*field)->maybe_null());
/*
assistance for backwards compatibility in production builds.
@@ -1494,7 +1486,10 @@ int ha_tina::create(const char *name, TABLE *table_arg,
for (Field **field= table_arg->s->field; *field; field++)
{
if ((*field)->real_maybe_null())
- DBUG_RETURN(-1);
+ {
+ my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "nullable columns");
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ }
}
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index f91b0dc7a92..4d3d8362a03 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -901,7 +901,14 @@ int ha_myisammrg::external_lock(THD *thd, int lock_type)
uint ha_myisammrg::lock_count(void) const
{
- DBUG_ASSERT(this->file->children_attached);
+ /*
+ Return the real lock count even if the children are not attached.
+ This method is used for allocating memory. If we would return 0
+ to another thread (e.g. doing FLUSH TABLE), and attach the children
+ before the other thread calls store_lock(), then we would return
+ more locks in store_lock() than we claimed by lock_count(). The
+ other tread would overrun its memory.
+ */
return file->tables;
}
@@ -911,7 +918,24 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
enum thr_lock_type lock_type)
{
MYRG_TABLE *open_table;
- DBUG_ASSERT(this->file->children_attached);
+
+ /*
+ This method can be called while another thread is attaching the
+ children. If the processor reorders instructions or write to memory,
+ 'children_attached' could be set before 'open_tables' has all the
+ pointers to the children. Use of a mutex here and in
+ myrg_attach_children() forces consistent data.
+ */
+ pthread_mutex_lock(&this->file->mutex);
+
+ /*
+ When MERGE table is open, but not yet attached, other threads
+ could flush it, which means call mysql_lock_abort_for_thread()
+ on this threads TABLE. 'children_attached' is FALSE in this
+ situaton. Since the table is not locked, return no lock data.
+ */
+ if (!this->file->children_attached)
+ goto end; /* purecov: tested */
for (open_table=file->open_tables ;
open_table != file->end_table ;
@@ -921,6 +945,9 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
if (lock_type != TL_IGNORE && open_table->table->lock.type == TL_UNLOCK)
open_table->table->lock.type=lock_type;
}
+
+ end:
+ pthread_mutex_unlock(&this->file->mutex);
return to;
}
diff --git a/storage/myisammrg/myrg_close.c b/storage/myisammrg/myrg_close.c
index b402a35a253..97216ed47fe 100644
--- a/storage/myisammrg/myrg_close.c
+++ b/storage/myisammrg/myrg_close.c
@@ -58,6 +58,7 @@ int myrg_close(MYRG_INFO *info)
pthread_mutex_lock(&THR_LOCK_open);
myrg_open_list=list_delete(myrg_open_list,&info->open_list);
pthread_mutex_unlock(&THR_LOCK_open);
+ VOID(pthread_mutex_destroy(&info->mutex));
my_free((uchar*) info,MYF(0));
if (error)
{
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index 6fb1888f84d..b5002116164 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -33,7 +33,7 @@
myrg_attach_children(). Please duplicate changes in these
functions or make common sub-functions.
*/
-/* purecov: begin unused */
+/* purecov: begin deadcode */ /* not used in MySQL server */
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
{
@@ -171,6 +171,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
VOID(my_close(fd,MYF(0)));
end_io_cache(&file);
+ VOID(pthread_mutex_init(&m_info->mutex, MY_MUTEX_INIT_FAST));
m_info->open_list.data=(void*) m_info;
pthread_mutex_lock(&THR_LOCK_open);
myrg_open_list=list_add(myrg_open_list,&m_info->open_list);
@@ -328,6 +329,7 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
end_io_cache(&file_cache);
VOID(my_close(fd, MYF(0)));
+ VOID(pthread_mutex_init(&m_info->mutex, MY_MUTEX_INIT_FAST));
m_info->open_list.data= (void*) m_info;
pthread_mutex_lock(&THR_LOCK_open);
@@ -393,6 +395,14 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
DBUG_ENTER("myrg_attach_children");
DBUG_PRINT("myrg", ("handle_locking: %d", handle_locking));
+ /*
+ This function can be called while another thread is trying to abort
+ locks of this MERGE table. If the processor reorders instructions or
+ write to memory, 'children_attached' could be set before
+ 'open_tables' has all the pointers to the children. Use of a mutex
+ here and in ha_myisammrg::store_lock() forces consistent data.
+ */
+ pthread_mutex_lock(&m_info->mutex);
rc= 1;
errpos= 0;
file_offset= 0;
@@ -464,6 +474,7 @@ int myrg_attach_children(MYRG_INFO *m_info, int handle_locking,
m_info->keys= min_keys;
m_info->last_used_table= m_info->open_tables;
m_info->children_attached= TRUE;
+ pthread_mutex_unlock(&m_info->mutex);
DBUG_RETURN(0);
err:
@@ -473,6 +484,7 @@ err:
my_free((char*) m_info->rec_per_key_part, MYF(0));
m_info->rec_per_key_part= NULL;
}
+ pthread_mutex_unlock(&m_info->mutex);
my_errno= save_errno;
DBUG_RETURN(1);
}
@@ -494,6 +506,8 @@ err:
int myrg_detach_children(MYRG_INFO *m_info)
{
DBUG_ENTER("myrg_detach_children");
+ /* For symmetry with myrg_attach_children() we use the mutex here. */
+ pthread_mutex_lock(&m_info->mutex);
if (m_info->tables)
{
/* Do not attach/detach an empty child list. */
@@ -504,6 +518,7 @@ int myrg_detach_children(MYRG_INFO *m_info)
m_info->del= 0;
m_info->data_file_length= 0;
m_info->options= 0;
+ pthread_mutex_unlock(&m_info->mutex);
DBUG_RETURN(0);
}