Commit 9209210d authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi
Browse files

Fix bug when repairing compressed MyISAM files

LOCATE() is now case sensitive
parent c6b3afe2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ make -k clean
/bin/rm -f */.deps/*.P config.cache innobase/config.cache bdb/build_unix/config.cache mysql-*.tar.gz
aclocal; autoheader; aclocal; automake; autoconf

CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared --without-extra-tools

make -j2
find . -name ".deps" | xargs rm -r 
+15 −3
Original line number Diff line number Diff line
@@ -6953,6 +6953,9 @@ version 4.0;
@itemize @bullet
@item
@code{LOCATE()} and @code{INSTR()} are case sensitive if neither
argument is a binary string.  binary strings.
@item
@code{INSERT INTO ... SELECT} had in 3.23 always @code{IGNORE} enabled.
In 4.0.1 MySQL will stop (and possible rollback) in case of an error if you
don't specify @code{IGNORE}.
@@ -28621,7 +28624,9 @@ mysql> select LOCATE('xbar', 'foobar');
        -> 0
@end example
This function is multi-byte safe.
This function is multi-byte safe.  In MySQL 3.23 this function is case
insensitive, while in 4.0 it's only case insensitive if either argument is
a binary string.
@findex LOCATE()
@item LOCATE(substr,str,pos)
@@ -28634,7 +28639,9 @@ mysql> select LOCATE('bar', 'foobarbar',5);
        -> 7
@end example
This function is multi-byte safe.
This function is multi-byte safe.  In MySQL 3.23 this function is case
insensitive, while in 4.0 it's only case insensitive if either argument is
a binary string.
@findex INSTR()
@item INSTR(str,substr)
@@ -28649,7 +28656,9 @@ mysql> select INSTR('xbar', 'foobar');
        -> 0
@end example
This function is multi-byte safe.
This function is multi-byte safe.  In MySQL 3.23 this function is case
insensitive, while in 4.0 it's only case insensitive if either argument is
a binary string.
@findex LPAD()
@item LPAD(str,len,padstr)
@@ -45786,6 +45795,9 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@itemize @bullet
@item
@code{LOCATE()} and @code{INSTR()} are case sensitive if neither
argument is a binary string.  binary strings.
@item
Fixed core dump bug in @code{UPDATE ... ORDER BY }.
@item
Changed @code{INSERT INTO .. SELECT} to by default stop on errors.
+47 −28
Original line number Diff line number Diff line
@@ -41,7 +41,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
		     ha_checksum *key_checksum, uint level);
static uint isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo);
static ha_checksum calc_checksum(ha_rows count);
static int writekeys(MI_INFO *info,byte *buff,my_off_t filepos);
static int writekeys(MI_CHECK *param, MI_INFO *info,byte *buff,
		     my_off_t filepos);
static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo,
			  my_off_t pagepos, File new_file);
static int sort_key_read(SORT_INFO *sort_info,void *key);
@@ -62,7 +63,8 @@ static void update_key_parts(MI_KEYDEF *keyinfo,
			     ulonglong *unique,
			     ulonglong records);
static ha_checksum mi_byte_checksum(const byte *buf, uint length);

static void set_data_file_type(MI_CHECK *param, SORT_INFO *info,
			       MYISAM_SHARE *share);

#ifdef __WIN__
static double ulonglong2double(ulonglong value)
@@ -1190,15 +1192,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
  sort_info->dupp=0;
  sort_info->fix_datafile= (my_bool) (! rep_quick);
  sort_info->max_records= ~(ha_rows) 0;
  if ((sort_info->new_data_file_type=share->data_file_type) ==
      COMPRESSED_RECORD && param->testflag & T_UNPACK)
  {
    if (share->options & HA_OPTION_PACK_RECORD)
      sort_info->new_data_file_type = DYNAMIC_RECORD;
    else
      sort_info->new_data_file_type = STATIC_RECORD;
  }

  set_data_file_type(param, sort_info, share);
  del=info->state->del;
  info->state->records=info->state->del=share->state.split=0;
  info->state->empty=0;
@@ -1226,9 +1221,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
  lock_memory(param);			/* Everything is alloced */
  while (!(error=sort_get_next_record(sort_info)))
  {
    if (writekeys(info,(byte*) sort_info->record,sort_info->filepos))
    if (writekeys(param, info,(byte*) sort_info->record,sort_info->filepos))
    {
      if (my_errno != HA_ERR_FOUND_DUPP_KEY) goto err;
      if (my_errno != HA_ERR_FOUND_DUPP_KEY)
	goto err;
      DBUG_DUMP("record",(byte*) sort_info->record,share->base.pack_reclength);
      mi_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s",
			  info->errkey+1,
@@ -1367,7 +1363,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,

/* Uppate keyfile when doing repair */

static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos)
static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff,
		     my_off_t filepos)
{
  register uint i;
  uchar *key;
@@ -1380,12 +1377,14 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos)
    {
      if (info->s->keyinfo[i].flag & HA_FULLTEXT )
      {
        if (_mi_ft_add(info,i,(char*) key,buff,filepos))  goto err;
        if (_mi_ft_add(info,i,(char*) key,buff,filepos))
	  goto err;
      }
      else
      {
	uint key_length=_mi_make_key(info,i,key,buff,filepos);
	if (_mi_ck_write(info,i,key,key_length)) goto err;
	if (_mi_ck_write(info,i,key,key_length))
	  goto err;
      }
    }
  }
@@ -1401,16 +1400,21 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos)
      {
	if (info->s->keyinfo[i].flag & HA_FULLTEXT)
        {
          if (_mi_ft_del(info,i,(char*) key,buff,filepos)) break;
          if (_mi_ft_del(info,i,(char*) key,buff,filepos))
	    break;
        }
        else
	{
	  uint key_length=_mi_make_key(info,i,key,buff,filepos);
	  if (_mi_ck_delete(info,i,key,key_length)) break;
	  if (_mi_ck_delete(info,i,key,key_length))
	    break;
	}
      }
    }
  }
  /* Remove checksum that was added to glob_crc in sort_get_next_record */
  if (param->calc_checksum)
    param->glob_crc-= info->checksum;
  DBUG_PRINT("error",("errno: %d",my_errno));
  DBUG_RETURN(-1);
} /* writekeys */
@@ -1847,15 +1851,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
  sort_info->info=info;
  sort_info->param = param;

  if ((sort_info->new_data_file_type=share->data_file_type) ==
      COMPRESSED_RECORD && param->testflag & T_UNPACK)
  {
    if (share->options & HA_OPTION_PACK_RECORD)
      sort_info->new_data_file_type = DYNAMIC_RECORD;
    else
      sort_info->new_data_file_type = STATIC_RECORD;
  }

  set_data_file_type(param, sort_info, share);
  sort_info->filepos=new_header_length;
  sort_info->dupp=0;
  sort_info->buff=0;
@@ -2193,7 +2189,8 @@ static int sort_get_next_record(SORT_INFO *sort_info)
      if (*sort_info->record)
      {
	if (param->calc_checksum)
	  param->glob_crc+= mi_static_checksum(info,sort_info->record);
	  param->glob_crc+= (info->checksum=
			     mi_static_checksum(info,sort_info->record));
	DBUG_RETURN(0);
      }
      if (!sort_info->fix_datafile)
@@ -2646,7 +2643,7 @@ static int sort_key_write(SORT_INFO *sort_info, const void *a)
						    sort_info->key_block->
						    lastkey),
				 llbuff2));
    param->error_printed=param->retry_without_quick=1;
    param->retry_without_quick=1;
    if (sort_info->param->testflag & T_VERBOSE)
      _mi_print_key(stdout,sort_info->keyseg,(uchar*) a, USE_WHOLE_KEY);
    return (sort_delete_record(param));
@@ -3291,3 +3288,25 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
  }
  return TRUE;
}


static void
set_data_file_type(MI_CHECK *param, SORT_INFO *sort_info, MYISAM_SHARE *share)
{
  if ((sort_info->new_data_file_type=share->data_file_type) ==
      COMPRESSED_RECORD && param->testflag & T_UNPACK)
  {
    MYISAM_SHARE tmp;

    if (share->options & HA_OPTION_PACK_RECORD)
      sort_info->new_data_file_type = DYNAMIC_RECORD;
    else
      sort_info->new_data_file_type = STATIC_RECORD;

    /* Set delete_function for sort_delete_record() */
    memcpy((char*) &tmp, share, sizeof(*share));
    tmp.options= ~HA_OPTION_COMPRESS_RECORD;
    mi_setup_functions(&tmp);
    share->delete_record=tmp.delete_record;
  }
}
+2 −3
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@
#include "static.c"
#endif

static void setup_functions(MYISAM_SHARE *info);
static void setup_key_functions(MI_KEYDEF *keyinfo);
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
					pos+=size;}
@@ -405,7 +404,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
    else if (share->options & HA_OPTION_PACK_RECORD)
      share->data_file_type = DYNAMIC_RECORD;
    my_afree((gptr) disk_cache);
    setup_functions(share);
    mi_setup_functions(share);
#ifdef THREAD
    thr_lock_init(&share->lock);
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
@@ -580,7 +579,7 @@ ulonglong mi_safe_mul(ulonglong a, ulonglong b)

	/* Set up functions in structs */

static void setup_functions(register MYISAM_SHARE *share)
void mi_setup_functions(register MYISAM_SHARE *share)
{
  if (share->options & HA_OPTION_COMPRESS_RECORD)
  {
+8 −1
Original line number Diff line number Diff line
@@ -785,7 +785,10 @@ static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to,
    if (bits <= 32)
    {
      if (bit_buff->pos > bit_buff->end+4)
      {
	bit_buff->error=1;
	return;				/* Can't be right */
      }
      bit_buff->current_byte= (bit_buff->current_byte << 32) +
	((((uint) bit_buff->pos[3])) +
	 (((uint) bit_buff->pos[2]) << 8) +
@@ -829,7 +832,8 @@ static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to,

#else

static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, uchar *end)
static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to,
			 uchar *end)
{
  reg1 uint bits,low_byte;
  reg3 uint16 *pos;
@@ -846,7 +850,10 @@ static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, uc
    if (bits < table_bits)
    {
      if (bit_buff->pos > bit_buff->end+1)
      {
	bit_buff->error=1;
	return;				/* Can't be right */
      }
#if BITS_SAVED == 32
      bit_buff->current_byte= (bit_buff->current_byte << 24) +
	(((uint) ((uchar) bit_buff->pos[2]))) +
Loading