summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <jani@a88-113-38-195.elisa-laajakaista.fi>2008-05-26 17:10:32 +0300
committerunknown <jani@a88-113-38-195.elisa-laajakaista.fi>2008-05-26 17:10:32 +0300
commit5ca17f0dc6235f03d9cbfcae087ac41d57fa4940 (patch)
treeeab2c68a3c78465c2b3a651bbae23640dcffcbba
parentc1a83aa9255c1cb7610ce8adc1ae91a3afbc38f1 (diff)
downloadmariadb-git-5ca17f0dc6235f03d9cbfcae087ac41d57fa4940.tar.gz
Logical merge of changes in myisam to maria.
-rw-r--r--storage/maria/ha_maria.cc87
-rw-r--r--storage/maria/ma_delete_all.c13
-rw-r--r--storage/maria/ma_dynrec.c18
-rw-r--r--storage/maria/ma_open.c10
-rw-r--r--storage/maria/ma_range.c2
5 files changed, 87 insertions, 43 deletions
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 53837a5e027..4a6bf0e25f0 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -557,7 +557,25 @@ int maria_check_definition(MARIA_KEYDEF *t1_keyinfo,
}
for (j= t1_keyinfo[i].keysegs; j--;)
{
- if (t1_keysegs[j].type != t2_keysegs[j].type ||
+ uint8 t1_keysegs_j__type= t1_keysegs[j].type;
+ /*
+ Table migration from 4.1 to 5.1. In 5.1 a *TEXT key part is
+ always HA_KEYTYPE_VARTEXT2. In 4.1 we had only the equivalent of
+ HA_KEYTYPE_VARTEXT1. Since we treat both the same on MyISAM
+ level, we can ignore a mismatch between these types.
+ */
+ if ((t1_keysegs[j].flag & HA_BLOB_PART) &&
+ (t2_keysegs[j].flag & HA_BLOB_PART))
+ {
+ if ((t1_keysegs_j__type == HA_KEYTYPE_VARTEXT2) &&
+ (t2_keysegs[j].type == HA_KEYTYPE_VARTEXT1))
+ t1_keysegs_j__type= HA_KEYTYPE_VARTEXT1; /* purecov: tested */
+ else if ((t1_keysegs_j__type == HA_KEYTYPE_VARBINARY2) &&
+ (t2_keysegs[j].type == HA_KEYTYPE_VARBINARY1))
+ t1_keysegs_j__type= HA_KEYTYPE_VARBINARY1; /* purecov: inspected */
+ }
+
+ if (t1_keysegs_j__type != t2_keysegs[j].type ||
t1_keysegs[j].language != t2_keysegs[j].language ||
t1_keysegs[j].null_bit != t2_keysegs[j].null_bit ||
t1_keysegs[j].length != t2_keysegs[j].length)
@@ -2433,6 +2451,7 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
share->avg_row_length);
create_info.data_file_name= ha_create_info->data_file_name;
create_info.index_file_name= ha_create_info->index_file_name;
+ create_info.language= share->table_charset->number;
/*
Table is transactional:
@@ -2812,8 +2831,7 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name,
*engine_callback,
ulonglong *engine_data)
{
- ulonglong actual_data_file_length;
- ulonglong current_data_file_length;
+ DBUG_ENTER("ha_maria::register_query_cache_table");
/*
No call back function is needed to determine if a cached statement
@@ -2826,39 +2844,50 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name,
*/
*engine_data= 0;
- /*
- If a concurrent INSERT has happened just before the currently processed
- SELECT statement, the total size of the table is unknown.
+ if (file->s->concurrent_insert)
+ {
+ /*
+ If a concurrent INSERT has happened just before the currently
+ processed SELECT statement, the total size of the table is
+ unknown.
- To determine if the table size is known, the current thread's snap shot of
- the table size with the actual table size are compared.
+ To determine if the table size is known, the current thread's snap
+ shot of the table size with the actual table size are compared.
- If the table size is unknown the SELECT statement can't be cached.
- */
+ If the table size is unknown the SELECT statement can't be cached.
- /*
- POSIX visibility rules specify that "2. Whatever memory values a
- thread can see when it unlocks a mutex <...> can also be seen by any
- thread that later locks the same mutex". In this particular case,
- concurrent insert thread had modified the data_file_length in
- MYISAM_SHARE before it has unlocked (or even locked)
- structure_guard_mutex. So, here we're guaranteed to see at least that
- value after we've locked the same mutex. We can see a later value
- (modified by some other thread) though, but it's ok, as we only want
- to know if the variable was changed, the actual new value doesn't matter
- */
- actual_data_file_length= file->s->state.state.data_file_length;
- current_data_file_length= file->save_state.data_file_length;
+ When concurrent inserts are disabled at table open, mi_open()
+ does not assign a get_status() function. In this case the local
+ ("current") status is never updated. We would wrongly think that
+ we cannot cache the statement.
+ */
+ ulonglong actual_data_file_length;
+ ulonglong current_data_file_length;
- if (!file->s->now_transactional &&
- current_data_file_length != actual_data_file_length)
- {
- /* Don't cache current statement. */
- return FALSE;
+ /*
+ POSIX visibility rules specify that "2. Whatever memory values a
+ thread can see when it unlocks a mutex <...> can also be seen by any
+ thread that later locks the same mutex". In this particular case,
+ concurrent insert thread had modified the data_file_length in
+ MYISAM_SHARE before it has unlocked (or even locked)
+ structure_guard_mutex. So, here we're guaranteed to see at least that
+ value after we've locked the same mutex. We can see a later value
+ (modified by some other thread) though, but it's ok, as we only want
+ to know if the variable was changed, the actual new value doesn't matter
+ */
+ actual_data_file_length= file->s->state.state.data_file_length;
+ current_data_file_length= file->save_state.data_file_length;
+
+ if (!file->s->now_transactional &&
+ current_data_file_length != actual_data_file_length)
+ {
+ /* Don't cache current statement. */
+ DBUG_RETURN(FALSE);
+ }
}
/* It is ok to try to cache current statement. */
- return TRUE;
+ DBUG_RETURN(TRUE);
}
#endif
diff --git a/storage/maria/ma_delete_all.c b/storage/maria/ma_delete_all.c
index 3f7f3110e28..07d54d853a0 100644
--- a/storage/maria/ma_delete_all.c
+++ b/storage/maria/ma_delete_all.c
@@ -88,6 +88,12 @@ int maria_delete_all_rows(MARIA_HA *info)
there may be data blocks there. We need to throw them away or they may
re-enter the emptied table or another table later.
*/
+
+#ifdef HAVE_MMAP
+ if (share->file_map)
+ _mi_unmap_file(info);
+#endif
+
if (_ma_flush_table_files(info, MARIA_FLUSH_DATA|MARIA_FLUSH_INDEX,
FLUSH_IGNORE_CHANGED, FLUSH_IGNORE_CHANGED) ||
my_chsize(info->dfile.file, 0, 0, MYF(MY_WME)) ||
@@ -119,10 +125,9 @@ int maria_delete_all_rows(MARIA_HA *info)
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
#ifdef HAVE_MMAP
- /* Resize mmaped area */
- rw_wrlock(&info->s->mmap_lock);
- _ma_remap_file(info, (my_off_t)0);
- rw_unlock(&info->s->mmap_lock);
+ /* Map again */
+ if (share->file_map)
+ _ma_dynmap_file(info, (my_off_t) 0);
#endif
allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(0);
diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c
index 4c124a31221..03dbb27cab1 100644
--- a/storage/maria/ma_dynrec.c
+++ b/storage/maria/ma_dynrec.c
@@ -1017,12 +1017,12 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
{
if (column->length > 255 && new_length > 127)
{
- to[0]=(char) ((new_length & 127)+128);
- to[1]=(char) (new_length >> 7);
+ to[0]= (uchar) ((new_length & 127) + 128);
+ to[1]= (uchar) (new_length >> 7);
to+=2;
}
else
- *to++= (char) new_length;
+ *to++= (uchar) new_length;
memcpy((uchar*) to,pos,(size_t) new_length); to+=new_length;
flag|=bit;
}
@@ -1056,7 +1056,7 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
}
if ((bit= bit << 1) >= 256)
{
- *packpos++ = (char) (uchar) flag;
+ *packpos++ = (uchar) flag;
bit=1; flag=0;
}
}
@@ -1066,7 +1066,7 @@ uint _ma_rec_pack(MARIA_HA *info, register uchar *to,
}
}
if (bit != 1)
- *packpos= (char) (uchar) flag;
+ *packpos= (uchar) flag;
if (info->s->calc_checksum)
*to++= (uchar) info->cur_row.checksum;
DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos)));
@@ -1143,12 +1143,14 @@ my_bool _ma_rec_check(MARIA_HA *info,const uchar *record, uchar *rec_buff,
goto err;
if (column->length > 255 && new_length > 127)
{
- if (to[0] != (char) ((new_length & 127)+128) ||
- to[1] != (char) (new_length >> 7))
+ /* purecov: begin inspected */
+ if (to[0] != (uchar) ((new_length & 127) + 128) ||
+ to[1] != (uchar) (new_length >> 7))
goto err;
to+=2;
+ /* purecov: end */
}
- else if (*to++ != (char) new_length)
+ else if (*to++ != (uchar) new_length)
goto err;
to+=new_length;
}
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index bdcc10508d8..3a29d0f8d67 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -714,7 +714,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
if (share->columndef[i].type == FIELD_BLOB)
{
share->blobs[j].pack_length=
- share->columndef[i].length-portable_sizeof_char_ptr;;
+ share->columndef[i].length-portable_sizeof_char_ptr;
share->blobs[j].offset= share->columndef[i].offset;
j++;
}
@@ -1028,6 +1028,14 @@ static void setup_key_functions(register MARIA_KEYDEF *keyinfo)
keyinfo->get_key= _ma_get_pack_key;
if (keyinfo->seg[0].flag & HA_PACK_KEY)
{ /* Prefix compression */
+ /*
+ _ma_prefix_search() compares end-space against ASCII blank (' ').
+ It cannot be used for character sets, that do not encode the
+ blank character like ASCII does. UCS2 is an example. All
+ character sets with a fixed width > 1 or a mimimum width > 1
+ cannot represent blank like ASCII does. In these cases we have
+ to use _ma_seq_search() for the search.
+ */
if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) ||
(keyinfo->seg->flag & HA_NULL_PART) ||
keyinfo->seg->charset->mbminlen > 1)
diff --git a/storage/maria/ma_range.c b/storage/maria/ma_range.c
index 056629319e5..5769095606a 100644
--- a/storage/maria/ma_range.c
+++ b/storage/maria/ma_range.c
@@ -147,7 +147,7 @@ static ha_rows _ma_record_pos(MARIA_HA *info, const uchar *key,
key_len=USE_WHOLE_KEY;
/*
- my_handler.c:mi_compare_text() has a flag 'skip_end_space'.
+ my_handler.c:ha_compare_text() has a flag 'skip_end_space'.
This is set in my_handler.c:ha_key_cmp() in dependence on the
compare flags 'nextflag' and the column type.