List:Commits« Previous MessageNext Message »
From:ingo Date:October 9 2006 8:25pm
Subject:bk commit into 5.1 tree (istruewing:1.2345)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of istruewing. When istruewing 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@stripped, 2006-10-09 22:24:55+02:00, istruewing@stripped +9 -0
  Merge chilla.local:/home/mydev/mysql-5.0-bug8283
  into  chilla.local:/home/mydev/mysql-5.1-bug8283
  MERGE: 1.1810.2114.25

  include/my_sys.h@stripped, 2006-10-09 22:20:18+02:00, istruewing@stripped +0 -0
    Auto merged
    MERGE: 1.178.7.1

  include/myisam.h@stripped, 2006-10-09 22:20:18+02:00, istruewing@stripped +0 -0
    Auto merged
    MERGE: 1.70.1.3

  mysql-test/r/myisam.result@stripped, 2006-10-09 22:20:19+02:00, istruewing@stripped +0 -0
    Auto merged
    MERGE: 1.71.1.18

  mysql-test/t/myisam.test@stripped, 2006-10-09 22:20:19+02:00, istruewing@stripped +0 -0
    Auto merged
    MERGE: 1.55.1.15

  storage/myisam/mi_check.c@stripped, 2006-10-09 22:24:51+02:00, istruewing@stripped +0 -0
    SCCS merged
    MERGE: 1.129.18.2

  storage/myisam/mi_check.c@stripped, 2006-10-09 22:20:18+02:00, istruewing@stripped +0 -0
    Merge rename: myisam/mi_check.c -> storage/myisam/mi_check.c

  storage/myisam/mi_open.c@stripped, 2006-10-09 22:20:19+02:00, istruewing@stripped +0 -0
    Auto merged
    MERGE: 1.90.6.2

  storage/myisam/mi_open.c@stripped, 2006-10-09 22:20:18+02:00, istruewing@stripped +0 -0
    Merge rename: myisam/mi_open.c -> storage/myisam/mi_open.c

  storage/myisam/mi_packrec.c@stripped, 2006-10-09 22:20:19+02:00, istruewing@stripped +0 -0
    Auto merged
    MERGE: 1.30.5.2

  storage/myisam/mi_packrec.c@stripped, 2006-10-09 22:20:18+02:00, istruewing@stripped +0 -0
    Merge rename: myisam/mi_packrec.c -> storage/myisam/mi_packrec.c

  storage/myisam/myisamdef.h@stripped, 2006-10-09 22:20:19+02:00, istruewing@stripped +0 -0
    Auto merged
    MERGE: 1.74.11.2

  storage/myisam/myisamdef.h@stripped, 2006-10-09 22:20:18+02:00, istruewing@stripped +0 -0
    Merge rename: myisam/myisamdef.h -> storage/myisam/myisamdef.h

  storage/myisam/sort.c@stripped, 2006-10-09 22:24:51+02:00, istruewing@stripped +0 -0
    SCCS merged
    MERGE: 1.45.7.2

  storage/myisam/sort.c@stripped, 2006-10-09 22:20:18+02:00, istruewing@stripped +0 -0
    Merge rename: myisam/sort.c -> storage/myisam/sort.c

# 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:	istruewing
# Host:	chilla.local
# Root:	/home/mydev/mysql-5.1-bug8283/RESYNC

--- 1.207/include/my_sys.h	2006-10-09 22:25:02 +02:00
+++ 1.208/include/my_sys.h	2006-10-09 22:25:02 +02:00
@@ -341,12 +341,18 @@ typedef int (*IO_CACHE_CALLBACK)(struct 
 #ifdef THREAD
 typedef struct st_io_cache_share
 {
-  /* to sync on reads into buffer */
-  pthread_mutex_t mutex;
-  pthread_cond_t  cond;
-  int             count, total;
-  /* actual IO_CACHE that filled the buffer */
-  struct st_io_cache *active;
+  pthread_mutex_t       mutex;           /* To sync on reads into buffer. */
+  pthread_cond_t        cond;            /* To wait for signals. */
+  pthread_cond_t        cond_writer;     /* For a synchronized writer. */
+  /* Offset in file corresponding to the first byte of buffer. */
+  my_off_t              pos_in_file;
+  /* If a synchronized write cache is the source of the data. */
+  struct st_io_cache    *source_cache;
+  byte                  *buffer;         /* The read buffer. */
+  byte                  *read_end;       /* Behind last valid byte of buffer. */
+  int                   running_threads; /* threads not in lock. */
+  int                   total_threads;   /* threads sharing the cache. */
+  int                   error;           /* Last error. */
 #ifdef NOT_YET_IMPLEMENTED
   /* whether the structure should be free'd */
   my_bool alloced;
@@ -719,8 +725,8 @@ extern void setup_io_cache(IO_CACHE* inf
 extern int _my_b_read(IO_CACHE *info,byte *Buffer,uint Count);
 #ifdef THREAD
 extern int _my_b_read_r(IO_CACHE *info,byte *Buffer,uint Count);
-extern void init_io_cache_share(IO_CACHE *info,
-				IO_CACHE_SHARE *s, uint num_threads);
+extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
+                                IO_CACHE *write_cache, uint num_threads);
 extern void remove_io_thread(IO_CACHE *info);
 #endif
 extern int _my_b_seq_read(IO_CACHE *info,byte *Buffer,uint Count);

--- 1.78/include/myisam.h	2006-10-09 22:25:02 +02:00
+++ 1.79/include/myisam.h	2006-10-09 22:25:02 +02:00
@@ -419,7 +419,7 @@ typedef struct st_mi_check_param
   uint testflag, key_cache_block_size;
   uint8 language;
   my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
-  my_bool retry_repair, force_sort, calc_checksum;
+  my_bool retry_repair, force_sort;
   char temp_filename[FN_REFLEN],*isam_file_name;
   MY_TMPDIR *tmpdir;
   int tmpfile_createflag;

--- 1.129.18.1/myisam/mi_check.c	2006-10-09 22:25:02 +02:00
+++ 1.153/storage/myisam/mi_check.c	2006-10-09 22:25:02 +02:00
@@ -382,7 +382,7 @@ int chk_key(MI_CHECK *param, register MI
     puts("- check key delete-chain");
 
   param->key_file_blocks=info->s->base.keystart;
-  for (key=0 ; key < info->s->state.header.max_block_size ; key++)
+  for (key=0 ; key < info->s->state.header.max_block_size_index ; key++)
     if (check_k_link(param,info,key))
     {
       if (param->testflag & T_VERBOSE) puts("");
@@ -1438,7 +1438,7 @@ int mi_repair(MI_CHECK *param, register 
     share->state.key_root[i]= HA_OFFSET_ERROR;
 
   /* Drop the delete chain. */
-  for (i=0 ; i < share->state.header.max_block_size ; i++)
+  for (i=0 ; i < share->state.header.max_block_size_index ; i++)
     share->state.key_del[i]=  HA_OFFSET_ERROR;
 
   /*
@@ -1824,7 +1824,7 @@ int mi_sort_index(MI_CHECK *param, regis
   info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
   for (key=0 ; key < info->s->base.keys ; key++)
     info->s->state.key_root[key]=index_pos[key];
-  for (key=0 ; key < info->s->state.header.max_block_size ; key++)
+  for (key=0 ; key < info->s->state.header.max_block_size_index ; key++)
     info->s->state.key_del[key]=  HA_OFFSET_ERROR;
 
   info->s->state.changed&= ~STATE_NOT_SORTED_PAGES;
@@ -2125,7 +2125,7 @@ int mi_repair_by_sort(MI_CHECK *param, r
     /* Clear the pointers to the given rows */
     for (i=0 ; i < share->base.keys ; i++)
       share->state.key_root[i]= HA_OFFSET_ERROR;
-    for (i=0 ; i < share->state.header.max_block_size ; i++)
+    for (i=0 ; i < share->state.header.max_block_size_index ; i++)
       share->state.key_del[i]=  HA_OFFSET_ERROR;
     info->state->key_file_length=share->base.keystart;
   }
@@ -2147,6 +2147,7 @@ int mi_repair_by_sort(MI_CHECK *param, r
     my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
 
   sort_param.wordlist=NULL;
+  init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
 
   if (share->data_file_type == DYNAMIC_RECORD)
     length=max(share->base.min_pack_length+1,share->base.min_block_length);
@@ -2209,12 +2210,36 @@ int mi_repair_by_sort(MI_CHECK *param, r
     {
       uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
                                     sort_param.keyinfo->seg->charset->mbmaxlen;
-      sort_info.max_records=
-        (ha_rows) (sort_info.filelength/ft_min_word_len+1);
+      sort_param.key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
+      /*
+        fulltext indexes may have much more entries than the
+        number of rows in the table. We estimate the number here.
+
+        Note, built-in parser is always nr. 0 - see ftparser_call_initializer()
+      */
+      if (sort_param.keyinfo->ftparser_nr == 0)
+      {
+        /*
+          for built-in parser the number of generated index entries
+          cannot be larger than the size of the data file divided
+          by the minimal word's length
+        */
+        sort_info.max_records=
+          (ha_rows) (sort_info.filelength/ft_min_word_len+1);
+      }
+      else
+      {
+        /*
+          for external plugin parser we cannot tell anything at all :(
+          so, we'll use all the sort memory and start from ~10 buffpeks.
+          (see _create_index_by_sort)
+        */
+        sort_info.max_records=
+          10*param->sort_buffer_length/sort_param.key_length;
+      }
 
       sort_param.key_read=sort_ft_key_read;
       sort_param.key_write=sort_ft_key_write;
-      sort_param.key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
     }
     else
     {
@@ -2231,6 +2256,7 @@ int mi_repair_by_sort(MI_CHECK *param, r
     }
     /* No need to calculate checksum again. */
     sort_param.calc_checksum= 0;
+    free_root(&sort_param.wordroot, MYF(0));
 
     /* Set for next loop */
     sort_info.max_records= (ha_rows) info->state->records;
@@ -2554,7 +2580,7 @@ int mi_repair_parallel(MI_CHECK *param, 
     /* Clear the pointers to the given rows */
     for (i=0 ; i < share->base.keys ; i++)
       share->state.key_root[i]= HA_OFFSET_ERROR;
-    for (i=0 ; i < share->state.header.max_block_size ; i++)
+    for (i=0 ; i < share->state.header.max_block_size_index ; i++)
       share->state.key_del[i]=  HA_OFFSET_ERROR;
     info->state->key_file_length=share->base.keystart;
   }
@@ -2679,6 +2705,7 @@ int mi_repair_parallel(MI_CHECK *param, 
       uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT*
                                     sort_param[i].keyinfo->seg->charset->mbmaxlen;
       sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN;
+      init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
     }
   }
   sort_info.total_keys=i;
@@ -2953,10 +2980,11 @@ static int sort_ft_key_read(MI_SORT_PARA
   {
     for (;;)
     {
-      my_free((char*) wptr, MYF(MY_ALLOW_ZERO_PTR));
+      free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
       if ((error=sort_get_next_record(sort_param)))
         DBUG_RETURN(error);
-      if (!(wptr=_mi_ft_parserecord(info,sort_param->key,sort_param->record)))
+      if (!(wptr=_mi_ft_parserecord(info,sort_param->key,sort_param->record,
+                                    &sort_param->wordroot)))
         DBUG_RETURN(1);
       if (wptr->pos)
         break;
@@ -2980,7 +3008,7 @@ static int sort_ft_key_read(MI_SORT_PARA
 #endif
   if (!wptr->pos)
   {
-    my_free((char*) sort_param->wordlist, MYF(0));
+    free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
     sort_param->wordlist=0;
     error=sort_write_record(sort_param);
   }
@@ -4112,9 +4140,6 @@ int recreate_table(MI_CHECK *param, MI_I
 
   create_info.data_file_length=file_length;
   create_info.auto_increment=share.state.auto_increment;
-  create_info.raid_type=   share.base.raid_type;
-  create_info.raid_chunks= share.base.raid_chunks;
-  create_info.raid_chunksize= share.base.raid_chunksize;
   create_info.language = (param->language ? param->language :
 			  share.state.header.language);
   create_info.key_file_length=  status_info.key_file_length;

--- 1.90.6.1/myisam/mi_open.c	2006-10-09 22:25:02 +02:00
+++ 1.104/storage/myisam/mi_open.c	2006-10-09 22:25:02 +02:00
@@ -95,7 +95,8 @@ MI_INFO *mi_open(const char *name, int m
   head_length=sizeof(share_buff.state.header);
   bzero((byte*) &info,sizeof(info));
 
-  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0));
+  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
+                                   MY_UNPACK_FILENAME),MYF(0));
   pthread_mutex_lock(&THR_LOCK_myisam);
   if (!(old_info=test_if_reopen(name_buff)))
   {
@@ -141,17 +142,27 @@ MI_INFO *mi_open(const char *name, int m
 	~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
 	  HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
 	  HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
-	  HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE))
+          HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
+          HA_OPTION_RELIES_ON_SQL_LAYER))
     {
       DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
       my_errno=HA_ERR_OLD_FILE;
       goto err;
     }
+    if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
+        ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
+    {
+      DBUG_PRINT("error", ("table cannot be openned from non-sql layer"));
+      my_errno= HA_ERR_UNSUPPORTED;
+      goto err;
+    }
     /* Don't call realpath() if the name can't be a link */
     if (!strcmp(name_buff, org_name) ||
         my_readlink(index_name, org_name, MYF(0)) == -1)
       (void) strmov(index_name, org_name);
-    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,2+4+16);
+    *strrchr(org_name, '.')= '\0';
+    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
+                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
 
     info_length=mi_uint2korr(share->state.header.header_length);
     base_pos=mi_uint2korr(share->state.header.base_pos);
@@ -197,9 +208,9 @@ MI_INFO *mi_open(const char *name, int m
     if (len != MI_BASE_INFO_SIZE)
     {
       DBUG_PRINT("warning",("saved_base_info_length: %d  base_info_length: %d",
-			    len,MI_BASE_INFO_SIZE))
+			    len,MI_BASE_INFO_SIZE));
     }
-    disk_pos= (char*) 
+    disk_pos= (char*)
       my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base);
     share->state.state_length=base_pos;
 
@@ -287,10 +298,11 @@ MI_INFO *mi_open(const char *name, int m
 			 &share->data_file_name,strlen(data_name)+1,
 			 &share->state.key_root,keys*sizeof(my_off_t),
 			 &share->state.key_del,
-			 (share->state.header.max_block_size*sizeof(my_off_t)),
+			 (share->state.header.max_block_size_index*sizeof(my_off_t)),
 #ifdef THREAD
 			 &share->key_root_lock,sizeof(rw_lock_t)*keys,
 #endif
+			 &share->mmap_lock,sizeof(rw_lock_t),
 			 NullS))
       goto err;
     errpos=4;
@@ -301,7 +313,7 @@ MI_INFO *mi_open(const char *name, int m
 	   (char*) key_root, sizeof(my_off_t)*keys);
     memcpy((char*) share->state.key_del,
 	   (char*) key_del, (sizeof(my_off_t) *
-			     share->state.header.max_block_size));
+			     share->state.header.max_block_size_index));
     strmov(share->unique_file_name, name_buff);
     share->unique_name_length= strlen(name_buff);
     strmov(share->index_file_name,  index_name);
@@ -420,6 +432,7 @@ MI_INFO *mi_open(const char *name, int m
 	pos->flag=0;
 	pos++;
       }
+      share->ftparsers= 0;
     }
 
     disk_pos_assert(disk_pos + share->base.fields *MI_COLUMNDEF_SIZE, end_pos);
@@ -462,7 +475,6 @@ MI_INFO *mi_open(const char *name, int m
 					(keys ? MI_INDEX_BLOCK_MARGIN *
 					 share->blocksize * keys : 0));
     share->blocksize=min(IO_SIZE,myisam_block_size);
-
     share->data_file_type=STATIC_RECORD;
     if (share->options & HA_OPTION_COMPRESS_RECORD)
     {
@@ -480,11 +492,13 @@ MI_INFO *mi_open(const char *name, int m
       share->data_file_type = DYNAMIC_RECORD;
     my_afree((gptr) disk_cache);
     mi_setup_functions(share);
+    share->is_log_table= FALSE;
 #ifdef THREAD
     thr_lock_init(&share->lock);
     VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
     for (i=0; i<keys; i++)
       VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
+    VOID(my_rwlock_init(&share->mmap_lock, NULL));
     if (!thr_lock_inited)
     {
       /* Probably a single threaded program; Don't use concurrent inserts */
@@ -739,6 +753,8 @@ void mi_setup_functions(register MYISAM_
     share->compare_unique=_mi_cmp_static_unique;
     share->calc_checksum= mi_static_checksum;
   }
+  share->file_read= mi_nommap_pread;
+  share->file_write= mi_nommap_pwrite;
   if (!(share->options & HA_OPTION_CHECKSUM))
     share->calc_checksum=0;
   return;
@@ -808,7 +824,7 @@ uint mi_state_info_write(File file, MI_S
   uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
   uchar *ptr=buff;
   uint	i, keys= (uint) state->header.keys,
-	key_blocks=state->header.max_block_size;
+	key_blocks=state->header.max_block_size_index;
   DBUG_ENTER("mi_state_info_write");
 
   memcpy_fixed(ptr,&state->header,sizeof(state->header));
@@ -874,7 +890,7 @@ uchar *mi_state_info_read(uchar *ptr, MI
   ptr +=sizeof(state->header);
   keys=(uint) state->header.keys;
   key_parts=mi_uint2korr(state->header.key_parts);
-  key_blocks=state->header.max_block_size;
+  key_blocks=state->header.max_block_size_index;
 
   state->open_count = mi_uint2korr(ptr);	ptr +=2;
   state->changed= (bool) *ptr++;
@@ -1047,9 +1063,11 @@ char *mi_keydef_read(char *ptr, MI_KEYDE
    keydef->keylength	= mi_uint2korr(ptr);	ptr +=2;
    keydef->minlength	= mi_uint2korr(ptr);	ptr +=2;
    keydef->maxlength	= mi_uint2korr(ptr);	ptr +=2;
-   keydef->block_size	= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
+   keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
    keydef->underflow_block_length=keydef->block_length/3;
    keydef->version	= 0;			/* Not saved */
+   keydef->parser       = &ft_default_parser;
+   keydef->ftparser_nr  = 0;
    return ptr;
 }
 

--- 1.30.5.1/myisam/mi_packrec.c	2006-10-09 22:25:02 +02:00
+++ 1.39/storage/myisam/mi_packrec.c	2006-10-09 22:25:02 +02:00
@@ -1191,56 +1191,33 @@ static uint max_bit(register uint value)
 static int _mi_read_mempack_record(MI_INFO *info,my_off_t filepos,byte *buf);
 static int _mi_read_rnd_mempack_record(MI_INFO*, byte *,my_off_t, my_bool);
 
-#ifndef MAP_NORESERVE
-#define MAP_NORESERVE 0		/* For irix */
-#endif
-#ifndef MAP_FAILED
-#define MAP_FAILED -1
-#endif
-
 my_bool _mi_memmap_file(MI_INFO *info)
 {
-  byte *file_map;
   MYISAM_SHARE *share=info->s;
   DBUG_ENTER("mi_memmap_file");
 
-  if (!share->file_map)
+  if (!info->s->file_map)
   {
-    my_off_t data_file_length= share->state.state.data_file_length;
-    if (data_file_length > (my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN)
-    {
-      DBUG_PRINT("warning", ("File is too large for mmap"));
-      DBUG_RETURN(0);
-    }
     if (my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)) <
-        data_file_length + MEMMAP_EXTRA_MARGIN)
+        share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN)
     {
       DBUG_PRINT("warning",("File isn't extended for memmap"));
       DBUG_RETURN(0);
     }
-    file_map=(byte*)
-      my_mmap(0, (size_t) (data_file_length + MEMMAP_EXTRA_MARGIN), PROT_READ,
-              MAP_SHARED | MAP_NORESERVE, info->dfile, 0L);
-    if (file_map == (byte*) MAP_FAILED)
-    {
-      DBUG_PRINT("warning",("mmap failed: errno: %d",errno));
-      my_errno=errno;
+    if (mi_dynmap_file(info, share->state.state.data_file_length))
       DBUG_RETURN(0);
-    }
-    share->file_map= file_map;
   }
   info->opt_flag|= MEMMAP_USED;
-  info->read_record=share->read_record=_mi_read_mempack_record;
-  share->read_rnd=_mi_read_rnd_mempack_record;
+  info->read_record= share->read_record= _mi_read_mempack_record;
+  share->read_rnd= _mi_read_rnd_mempack_record;
   DBUG_RETURN(1);
 }
 
 
 void _mi_unmap_file(MI_INFO *info)
 {
-  VOID(my_munmap(info->s->file_map,
-	      (size_t) info->s->state.state.data_file_length+
-	      MEMMAP_EXTRA_MARGIN));
+  VOID(my_munmap(info->s->file_map, 
+                 (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN));
 }
 
 

--- 1.74.11.1/myisam/myisamdef.h	2006-10-09 22:25:02 +02:00
+++ 1.92/storage/myisam/myisamdef.h	2006-10-09 22:25:02 +02:00
@@ -55,7 +55,7 @@ typedef struct st_mi_state_info
     uchar keys;				/* number of keys in file */
     uchar uniques;			/* number of UNIQUE definitions */
     uchar language;			/* Language for indexes */
-    uchar max_block_size;		/* max keyblock size */
+    uchar max_block_size_index;		/* max keyblock size */
     uchar fulltext_keys;
     uchar not_used;                     /* To align to 8 */
   } header;
@@ -153,6 +153,7 @@ typedef struct st_mi_isam_pack {
   uchar version;
 } MI_PACK;
 
+#define MAX_NONMAPPED_INSERTS 1000      
 
 typedef struct st_mi_isam_share {	/* Shared between opens */
   MI_STATE_INFO state;
@@ -181,6 +182,8 @@ typedef struct st_mi_isam_share {	/* Sha
   ha_checksum (*calc_checksum)(struct st_myisam_info*, const byte *);
   int (*compare_unique)(struct st_myisam_info*, MI_UNIQUEDEF *,
 			const byte *record, my_off_t pos);
+  uint (*file_read)(MI_INFO *, byte *, uint, my_off_t, myf);
+  uint (*file_write)(MI_INFO *, byte *, uint, my_off_t, myf);
   invalidator_by_filename invalidator;  /* query cache invalidator */
   ulong this_process;			/* processid */
   ulong last_process;			/* For table-change-check */
@@ -191,6 +194,7 @@ typedef struct st_mi_isam_share {	/* Sha
   ulong state_diff_length;
   uint	rec_reflength;			/* rec_reflength in use now */
   uint  unique_name_length;
+  uint32 ftparsers;                     /* Number of distinct ftparsers + 1 */
   File	kfile;				/* Shared keyfile */
   File	data_file;			/* Shared data file */
   int	mode;				/* mode of file on open */
@@ -199,6 +203,9 @@ typedef struct st_mi_isam_share {	/* Sha
   uint	blocksize;			/* blocksize of keyfile */
   myf write_flag;
   enum data_file_type data_file_type;
+  /* Below flag is needed to make log tables work with concurrent insert */
+  my_bool is_log_table;
+
   my_bool  changed,			/* If changed since lock */
     global_changed,			/* If changed since open */
     not_flushed,
@@ -209,6 +216,10 @@ typedef struct st_mi_isam_share {	/* Sha
   pthread_mutex_t intern_lock;		/* Locking for use with _locking */
   rw_lock_t *key_root_lock;
 #endif
+  my_off_t mmaped_length;
+  uint     nonmmaped_inserts;           /* counter of writing in non-mmaped
+                                           area */
+  rw_lock_t mmap_lock;
 } MYISAM_SHARE;
 
 
@@ -229,12 +240,14 @@ struct st_myisam_info {
   /* accumulate indexfile changes between write's */
   TREE	        *bulk_insert;
   DYNAMIC_ARRAY *ft1_to_ft2;            /* used only in ft1->ft2 conversion */
-  char *filename;			/* parameter to open filename */
-  uchar *buff,				/* Temp area for key */
-	*lastkey,*lastkey2;		/* Last used search key */
-  uchar *first_mbr_key;			/* Searhed spatial key */ 
-  byte	*rec_buff;			/* Tempbuff for recordpack */
-  uchar *int_keypos,			/* Save position for next/previous */
+  MEM_ROOT      ft_memroot;             /* used by the parser               */
+  MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit   */
+  char *filename;			/* parameter to open filename       */
+  uchar *buff,				/* Temp area for key                */
+	*lastkey,*lastkey2;		/* Last used search key             */
+  uchar *first_mbr_key;			/* Searhed spatial key              */
+  byte	*rec_buff;			/* Tempbuff for recordpack          */
+  uchar *int_keypos,			/* Save position for next/previous  */
         *int_maxpos;			/*  -""-  */
   uint  int_nod_flag;			/*  -""-  */
   uint32 int_keytree_version;		/*  -""-  */
@@ -280,6 +293,9 @@ struct st_myisam_info {
   my_bool page_changed;		/* If info->buff can't be used for rnext */
   my_bool buff_used;		/* If info->buff has to be reread for rnext */
   my_bool once_flags;           /* For MYISAMMRG */
+#ifdef __WIN__
+  my_bool owned_by_merge;                       /* This MyISAM table is part of a merge union */
+#endif
 #ifdef THREAD
   THR_LOCK_DATA lock;
 #endif
@@ -320,6 +336,7 @@ typedef struct st_mi_sort_param
   uchar **sort_keys;
   byte *rec_buff;
   void *wordlist, *wordptr;
+  MEM_ROOT wordroot;
   char *record;
   MY_TMPDIR *tmpdir;
   int (*key_cmp)(struct st_mi_sort_param *, const void *, const void *);
@@ -433,7 +450,7 @@ typedef struct st_mi_sort_param
 #define MI_FOUND_WRONG_KEY 32738	/* Impossible value from ha_key_cmp */
 
 #define MI_MAX_KEY_BLOCK_SIZE	(MI_MAX_KEY_BLOCK_LENGTH/MI_MIN_KEY_BLOCK_LENGTH)
-#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/myisam_block_size+1)*myisam_block_size)
+#define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer,block_size) (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/(block_size)+1)*(block_size))
 #define MI_MAX_KEYPTR_SIZE	5        /* For calculating block lengths */
 #define MI_MIN_KEYBLOCK_LENGTH	50         /* When to split delete blocks */
 
@@ -698,6 +715,14 @@ extern void _mi_unmap_file(MI_INFO *info
 extern uint save_pack_length(uint version, byte *block_buff, ulong length);
 extern uint read_pack_length(uint version, const uchar *buf, ulong *length);
 extern uint calc_pack_length(uint version, ulong length);
+extern uint mi_mmap_pread(MI_INFO *info, byte *Buffer,
+                           uint Count, my_off_t offset, myf MyFlags);
+extern uint mi_mmap_pwrite(MI_INFO *info, byte *Buffer,
+                            uint Count, my_off_t offset, myf MyFlags);
+extern uint mi_nommap_pread(MI_INFO *info, byte *Buffer,
+                             uint Count, my_off_t offset, myf MyFlags);
+extern uint mi_nommap_pwrite(MI_INFO *info, byte *Buffer,
+                             uint Count, my_off_t offset, myf MyFlags);
 
 uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite);
 uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state);
@@ -738,6 +763,8 @@ my_bool check_table_is_closed(const char
 int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup);
 int mi_open_keyfile(MYISAM_SHARE *share);
 void mi_setup_functions(register MYISAM_SHARE *share);
+my_bool mi_dynmap_file(MI_INFO *info, my_off_t size);
+void mi_remap_file(MI_INFO *info, my_off_t size);
 
     /* Functions needed by mi_check */
 volatile int *killed_ptr(MI_CHECK *param);

--- 1.45.7.1/myisam/sort.c	2006-10-09 22:25:02 +02:00
+++ 1.54/storage/myisam/sort.c	2006-10-09 22:25:02 +02:00
@@ -455,6 +455,7 @@ err:
   close_cached_file(&sort_param->tempfile_for_exceptions);
 
 ok:
+  free_root(&info->wordroot, MYF(0));
   /*
     Detach from the share if the writer is involved. Avoid others to
     be blocked. This includes a flush of the write buffer. This will

--- 1.95/mysql-test/r/myisam.result	2006-10-09 22:25:02 +02:00
+++ 1.96/mysql-test/r/myisam.result	2006-10-09 22:25:02 +02:00
@@ -796,6 +796,132 @@ a	b
 xxxxxxxxx	bbbbbb
 xxxxxxxxx	bbbbbb
 DROP TABLE t1;
+SET @@myisam_repair_threads=2;
+SHOW VARIABLES LIKE 'myisam_repair%';
+Variable_name	Value
+myisam_repair_threads	2
+CREATE TABLE t1 (
+`_id` int(11) NOT NULL default '0',
+`url` text,
+`email` text,
+`description` text,
+`loverlap` int(11) default NULL,
+`roverlap` int(11) default NULL,
+`lneighbor_id` int(11) default NULL,
+`rneighbor_id` int(11) default NULL,
+`length_` int(11) default NULL,
+`sequence` mediumtext,
+`name` text,
+`_obj_class` text NOT NULL,
+PRIMARY KEY  (`_id`),
+UNIQUE KEY `sequence_name_index` (`name`(50)),
+KEY (`length_`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES
+(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
+(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
+(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
+(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
+(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
+(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
+(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
+(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
+(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
+SELECT _id FROM t1;
+_id
+1
+2
+3
+4
+5
+6
+7
+8
+9
+DELETE FROM t1 WHERE _id < 8;
+SHOW TABLE STATUS LIKE 't1';
+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	MyISAM	10	Dynamic	2	#	#	#	#	140	#	#	#	#	#	#		
+CHECK TABLE t1 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+OPTIMIZE TABLE t1;
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+CHECK TABLE t1 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+SHOW TABLE STATUS LIKE 't1';
+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	MyISAM	10	Dynamic	2	#	#	#	#	0	#	#	#	#	#	#		
+SELECT _id FROM t1;
+_id
+8
+9
+DROP TABLE t1;
+CREATE TABLE t1 (
+`_id` int(11) NOT NULL default '0',
+`url` text,
+`email` text,
+`description` text,
+`loverlap` int(11) default NULL,
+`roverlap` int(11) default NULL,
+`lneighbor_id` int(11) default NULL,
+`rneighbor_id` int(11) default NULL,
+`length_` int(11) default NULL,
+`sequence` mediumtext,
+`name` text,
+`_obj_class` text NOT NULL,
+PRIMARY KEY  (`_id`),
+UNIQUE KEY `sequence_name_index` (`name`(50)),
+KEY (`length_`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES
+(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
+(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
+(3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
+(4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
+(5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
+(6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
+(7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
+(8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
+(9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
+SELECT _id FROM t1;
+_id
+1
+2
+3
+4
+5
+6
+7
+8
+9
+DELETE FROM t1 WHERE _id < 8;
+SHOW TABLE STATUS LIKE 't1';
+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	MyISAM	10	Dynamic	2	#	#	#	#	140	#	#	#	#	#	#		
+CHECK TABLE t1 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+REPAIR TABLE t1 QUICK;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+CHECK TABLE t1 EXTENDED;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
+SHOW TABLE STATUS LIKE 't1';
+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	MyISAM	10	Dynamic	2	#	#	#	#	140	#	#	#	#	#	#		
+SELECT _id FROM t1;
+_id
+8
+9
+DROP TABLE t1;
+SET @@myisam_repair_threads=1;
+SHOW VARIABLES LIKE 'myisam_repair%';
+Variable_name	Value
+myisam_repair_threads	1
 set storage_engine=MyISAM;
 drop table if exists t1,t2,t3;
 --- Testing varchar ---

--- 1.70/mysql-test/t/myisam.test	2006-10-09 22:25:02 +02:00
+++ 1.71/mysql-test/t/myisam.test	2006-10-09 22:25:02 +02:00
@@ -755,6 +755,97 @@ SELECT * FROM t1;
 DROP TABLE t1;
 
 #
+# Bug#8283 - OPTIMIZE TABLE causes data loss
+#
+SET @@myisam_repair_threads=2;
+SHOW VARIABLES LIKE 'myisam_repair%';
+#
+# Test OPTIMIZE. This creates a new data file.
+CREATE TABLE t1 (
+  `_id` int(11) NOT NULL default '0',
+  `url` text,
+  `email` text,
+  `description` text,
+  `loverlap` int(11) default NULL,
+  `roverlap` int(11) default NULL,
+  `lneighbor_id` int(11) default NULL,
+  `rneighbor_id` int(11) default NULL,
+  `length_` int(11) default NULL,
+  `sequence` mediumtext,
+  `name` text,
+  `_obj_class` text NOT NULL,
+  PRIMARY KEY  (`_id`),
+  UNIQUE KEY `sequence_name_index` (`name`(50)),
+  KEY (`length_`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+#
+INSERT INTO t1 VALUES
+  (1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
+  (2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
+  (3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
+  (4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
+  (5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
+  (6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
+  (7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
+  (8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
+  (9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
+#
+SELECT _id FROM t1;
+DELETE FROM t1 WHERE _id < 8;
+--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
+SHOW TABLE STATUS LIKE 't1';
+CHECK TABLE t1 EXTENDED;
+OPTIMIZE TABLE t1;
+CHECK TABLE t1 EXTENDED;
+--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
+SHOW TABLE STATUS LIKE 't1';
+SELECT _id FROM t1;
+DROP TABLE t1;
+#
+# Test REPAIR QUICK. This retains the old data file.
+CREATE TABLE t1 (
+  `_id` int(11) NOT NULL default '0',
+  `url` text,
+  `email` text,
+  `description` text,
+  `loverlap` int(11) default NULL,
+  `roverlap` int(11) default NULL,
+  `lneighbor_id` int(11) default NULL,
+  `rneighbor_id` int(11) default NULL,
+  `length_` int(11) default NULL,
+  `sequence` mediumtext,
+  `name` text,
+  `_obj_class` text NOT NULL,
+  PRIMARY KEY  (`_id`),
+  UNIQUE KEY `sequence_name_index` (`name`(50)),
+  KEY (`length_`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+#
+INSERT INTO t1 VALUES
+  (1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample1',''),
+  (2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample2',''),
+  (3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample3',''),
+  (4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample4',''),
+  (5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample5',''),
+  (6,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample6',''),
+  (7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample7',''),
+  (8,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample8',''),
+  (9,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'sample9','');
+#
+SELECT _id FROM t1;
+DELETE FROM t1 WHERE _id < 8;
+--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
+SHOW TABLE STATUS LIKE 't1';
+CHECK TABLE t1 EXTENDED;
+REPAIR TABLE t1 QUICK;
+CHECK TABLE t1 EXTENDED;
+--replace_column 6 # 7 # 8 # 9 # 11 # 12 # 13 # 14 # 15 # 16 #
+SHOW TABLE STATUS LIKE 't1';
+SELECT _id FROM t1;
+DROP TABLE t1;
+#
+SET @@myisam_repair_threads=1;
+SHOW VARIABLES LIKE 'myisam_repair%';
 # Test varchar
 #
 
Thread
bk commit into 5.1 tree (istruewing:1.2345)ingo9 Oct