2009-12-04 18:26:15 -07:00
|
|
|
/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
|
2001-12-06 14:10:51 +02:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2006-12-23 20:17:15 +01:00
|
|
|
the Free Software Foundation; version 2 of the License.
|
2001-12-06 14:10:51 +02:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2001-12-06 14:10:51 +02:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
|
|
|
|
/* open a isam-database */
|
|
|
|
|
|
|
|
#include "fulltext.h"
|
2002-02-20 14:11:21 +04:00
|
|
|
#include "sp_defs.h"
|
|
|
|
#include "rt_index.h"
|
2000-07-31 21:29:14 +02:00
|
|
|
#include <m_ctype.h>
|
|
|
|
|
|
|
|
#ifdef __WIN__
|
|
|
|
#include <fcntl.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void setup_key_functions(MI_KEYDEF *keyinfo);
|
|
|
|
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
|
|
|
|
pos+=size;}
|
|
|
|
|
|
|
|
|
2003-03-11 21:25:17 +02:00
|
|
|
#define disk_pos_assert(pos, end_pos) \
|
|
|
|
if (pos > end_pos) \
|
|
|
|
{ \
|
|
|
|
my_errno=HA_ERR_CRASHED; \
|
|
|
|
goto err; \
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
/******************************************************************************
|
|
|
|
** Return the shared struct if the table is already open.
|
|
|
|
** In MySQL the server will handle version issues.
|
|
|
|
******************************************************************************/
|
|
|
|
|
2005-03-02 10:35:00 +01:00
|
|
|
MI_INFO *test_if_reopen(char *filename)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
LIST *pos;
|
|
|
|
|
|
|
|
for (pos=myisam_open_list ; pos ; pos=pos->next)
|
|
|
|
{
|
|
|
|
MI_INFO *info=(MI_INFO*) pos->data;
|
|
|
|
MYISAM_SHARE *share=info->s;
|
2001-05-31 14:07:17 +03:00
|
|
|
if (!strcmp(share->unique_file_name,filename) && share->last_version)
|
2000-07-31 21:29:14 +02:00
|
|
|
return info;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
2000-09-26 00:33:25 +03:00
|
|
|
open a MyISAM database.
|
|
|
|
See my_base.h for the handle_locking argument
|
|
|
|
if handle_locking and HA_OPEN_ABORT_IF_CRASHED then abort if the table
|
|
|
|
is marked crashed or if we are not using locking and the table doesn't
|
|
|
|
have an open count of 0.
|
2000-07-31 21:29:14 +02:00
|
|
|
******************************************************************************/
|
|
|
|
|
2000-09-26 00:33:25 +03:00
|
|
|
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2008-08-22 17:31:53 +05:00
|
|
|
int lock_error,kfile,open_mode,save_errno,have_rtree=0, realpath_err;
|
2002-07-23 18:31:22 +03:00
|
|
|
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
|
2003-01-21 19:24:34 +01:00
|
|
|
key_parts,unique_key_parts,fulltext_keys,uniques;
|
2005-06-21 18:18:58 +03:00
|
|
|
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
|
2001-05-31 14:07:17 +03:00
|
|
|
data_name[FN_REFLEN];
|
2007-08-13 16:11:25 +03:00
|
|
|
uchar *disk_cache, *disk_pos, *end_pos;
|
2000-07-31 21:29:14 +02:00
|
|
|
MI_INFO info,*m_info,*old_info;
|
|
|
|
MYISAM_SHARE share_buff,*share;
|
2007-10-11 18:07:40 +03:00
|
|
|
ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
|
|
|
|
my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
|
2000-07-31 21:29:14 +02:00
|
|
|
ulonglong max_key_file_length, max_data_file_length;
|
|
|
|
DBUG_ENTER("mi_open");
|
|
|
|
|
|
|
|
LINT_INIT(m_info);
|
|
|
|
kfile= -1;
|
|
|
|
lock_error=1;
|
|
|
|
errpos=0;
|
|
|
|
head_length=sizeof(share_buff.state.header);
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 12:59:39 +03:00
|
|
|
bzero((uchar*) &info,sizeof(info));
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2008-08-22 17:31:53 +05:00
|
|
|
realpath_err= my_realpath(name_buff,
|
|
|
|
fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0));
|
|
|
|
if (my_is_symlink(org_name) &&
|
|
|
|
(realpath_err || (*myisam_test_invalid_symlink)(name_buff)))
|
|
|
|
{
|
|
|
|
my_errno= HA_WRONG_CREATE_OPTION;
|
|
|
|
DBUG_RETURN (NULL);
|
|
|
|
}
|
|
|
|
|
2009-12-04 18:26:15 -07:00
|
|
|
mysql_mutex_lock(&THR_LOCK_myisam);
|
2000-07-31 21:29:14 +02:00
|
|
|
if (!(old_info=test_if_reopen(name_buff)))
|
|
|
|
{
|
|
|
|
share= &share_buff;
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 12:59:39 +03:00
|
|
|
bzero((uchar*) &share_buff,sizeof(share_buff));
|
2000-07-31 21:29:14 +02:00
|
|
|
share_buff.state.rec_per_key_part=rec_per_key_part;
|
|
|
|
share_buff.state.key_root=key_root;
|
|
|
|
share_buff.state.key_del=key_del;
|
2007-08-13 16:11:25 +03:00
|
|
|
share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
|
|
|
|
strlen(name_buff));
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2004-12-23 20:11:38 +01:00
|
|
|
DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open",
|
|
|
|
if (strstr(name, "/t1"))
|
|
|
|
{
|
|
|
|
my_errno= HA_ERR_CRASHED;
|
|
|
|
goto err;
|
|
|
|
});
|
2009-12-04 18:26:15 -07:00
|
|
|
if ((kfile= mysql_file_open(mi_key_file_kfile,
|
|
|
|
name_buff,
|
|
|
|
(open_mode= O_RDWR) | O_SHARE, MYF(0))) < 0)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
if ((errno != EROFS && errno != EACCES) ||
|
|
|
|
mode != O_RDONLY ||
|
2009-12-04 18:26:15 -07:00
|
|
|
(kfile= mysql_file_open(mi_key_file_kfile,
|
|
|
|
name_buff,
|
|
|
|
(open_mode= O_RDONLY) | O_SHARE, MYF(0))) < 0)
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
|
|
|
}
|
2000-10-17 00:47:15 +03:00
|
|
|
share->mode=open_mode;
|
2000-07-31 21:29:14 +02:00
|
|
|
errpos=1;
|
2009-12-04 18:26:15 -07:00
|
|
|
if (mysql_file_read(kfile, share->state.header.file_version, head_length,
|
|
|
|
MYF(MY_NABP)))
|
2003-05-14 01:27:26 +03:00
|
|
|
{
|
|
|
|
my_errno= HA_ERR_NOT_A_TABLE;
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
2003-05-14 01:27:26 +03:00
|
|
|
}
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 12:59:39 +03:00
|
|
|
if (memcmp((uchar*) share->state.header.file_version,
|
|
|
|
(uchar*) myisam_file_magic, 4))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
DBUG_PRINT("error",("Wrong header in %s",name_buff));
|
2010-05-26 16:12:23 +02:00
|
|
|
DBUG_DUMP("error_dump", share->state.header.file_version,
|
2000-07-31 21:29:14 +02:00
|
|
|
head_length);
|
2003-01-28 17:42:08 +01:00
|
|
|
my_errno=HA_ERR_NOT_A_TABLE;
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
share->options= mi_uint2korr(share->state.header.options);
|
|
|
|
if (share->options &
|
|
|
|
~(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 |
|
2005-12-28 16:05:30 +04:00
|
|
|
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
|
|
|
|
HA_OPTION_RELIES_ON_SQL_LAYER))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2003-01-21 19:24:34 +01:00
|
|
|
DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
|
2000-07-31 21:29:14 +02:00
|
|
|
my_errno=HA_ERR_OLD_FILE;
|
|
|
|
goto err;
|
|
|
|
}
|
2005-12-28 16:05:30 +04:00
|
|
|
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;
|
|
|
|
}
|
2001-05-31 14:07:17 +03:00
|
|
|
/* Don't call realpath() if the name can't be a link */
|
2005-01-18 03:49:39 +02:00
|
|
|
if (!strcmp(name_buff, org_name) ||
|
2005-01-15 20:08:53 +01:00
|
|
|
my_readlink(index_name, org_name, MYF(0)) == -1)
|
2001-06-01 04:27:59 +03:00
|
|
|
(void) strmov(index_name, org_name);
|
2005-12-31 09:01:26 +04:00
|
|
|
*strrchr(org_name, '.')= '\0';
|
|
|
|
(void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
|
|
|
|
MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
|
2001-05-31 14:07:17 +03:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
info_length=mi_uint2korr(share->state.header.header_length);
|
|
|
|
base_pos=mi_uint2korr(share->state.header.base_pos);
|
2007-08-13 16:11:25 +03:00
|
|
|
if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
my_errno=ENOMEM;
|
|
|
|
goto err;
|
|
|
|
}
|
2003-03-10 16:48:13 +01:00
|
|
|
end_pos=disk_cache+info_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
errpos=2;
|
|
|
|
|
2009-12-04 18:26:15 -07:00
|
|
|
mysql_file_seek(kfile, 0L, MY_SEEK_SET, MYF(0));
|
2000-09-26 00:33:25 +03:00
|
|
|
if (!(open_flags & HA_OPEN_TMP_TABLE))
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
|
2000-09-26 00:33:25 +03:00
|
|
|
MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
|
2000-07-31 21:29:14 +02:00
|
|
|
0 : MY_DONT_WAIT))) &&
|
2000-09-26 00:33:25 +03:00
|
|
|
!(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
errpos=3;
|
2009-12-04 18:26:15 -07:00
|
|
|
if (mysql_file_read(kfile, disk_cache, info_length, MYF(MY_NABP)))
|
2003-05-14 01:27:26 +03:00
|
|
|
{
|
|
|
|
my_errno=HA_ERR_CRASHED;
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
2003-05-14 01:27:26 +03:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
len=mi_uint2korr(share->state.header.state_info_length);
|
|
|
|
keys= (uint) share->state.header.keys;
|
|
|
|
uniques= (uint) share->state.header.uniques;
|
2003-01-21 19:24:34 +01:00
|
|
|
fulltext_keys= (uint) share->state.header.fulltext_keys;
|
2000-07-31 21:29:14 +02:00
|
|
|
key_parts= mi_uint2korr(share->state.header.key_parts);
|
|
|
|
unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
|
|
|
|
if (len != MI_STATE_INFO_SIZE)
|
|
|
|
{
|
|
|
|
DBUG_PRINT("warning",
|
|
|
|
("saved_state_info_length: %d state_info_length: %d",
|
|
|
|
len,MI_STATE_INFO_SIZE));
|
|
|
|
}
|
|
|
|
share->state_diff_length=len-MI_STATE_INFO_SIZE;
|
|
|
|
|
2007-08-13 16:11:25 +03:00
|
|
|
mi_state_info_read(disk_cache, &share->state);
|
2000-07-31 21:29:14 +02:00
|
|
|
len= mi_uint2korr(share->state.header.base_info_length);
|
|
|
|
if (len != MI_BASE_INFO_SIZE)
|
|
|
|
{
|
|
|
|
DBUG_PRINT("warning",("saved_base_info_length: %d base_info_length: %d",
|
2006-02-14 22:36:11 +01:00
|
|
|
len,MI_BASE_INFO_SIZE));
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2007-08-13 16:11:25 +03:00
|
|
|
disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
|
2000-07-31 21:29:14 +02:00
|
|
|
share->state.state_length=base_pos;
|
|
|
|
|
2000-10-11 00:06:37 +03:00
|
|
|
if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
|
2000-09-26 00:33:25 +03:00
|
|
|
((share->state.changed & STATE_CRASHED) ||
|
2000-10-11 00:06:37 +03:00
|
|
|
((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
|
|
|
|
(my_disable_locking && share->state.open_count))))
|
2000-09-26 00:33:25 +03:00
|
|
|
{
|
2006-10-09 19:26:55 +02:00
|
|
|
DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u "
|
|
|
|
"changed: %u open_count: %u !locking: %d",
|
|
|
|
open_flags, share->state.changed,
|
|
|
|
share->state.open_count, my_disable_locking));
|
2000-09-26 00:33:25 +03:00
|
|
|
my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
|
2000-11-21 03:43:34 +02:00
|
|
|
HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
|
2000-09-26 00:33:25 +03:00
|
|
|
goto err;
|
|
|
|
}
|
2001-01-15 17:17:43 +02:00
|
|
|
|
|
|
|
/* sanity check */
|
|
|
|
if (share->base.keystart > 65535 || share->base.rec_reflength > 8)
|
|
|
|
{
|
|
|
|
my_errno=HA_ERR_CRASHED;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2003-01-21 19:24:34 +01:00
|
|
|
key_parts+=fulltext_keys*FT_SEGS;
|
2001-01-15 17:17:43 +02:00
|
|
|
if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
|
2007-06-27 14:35:49 +03:00
|
|
|
key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
|
2001-01-15 17:17:43 +02:00
|
|
|
{
|
|
|
|
DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
|
|
|
|
my_errno=HA_ERR_UNSUPPORTED;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2003-01-21 19:24:34 +01:00
|
|
|
/* Correct max_file_length based on length of sizeof(off_t) */
|
2000-07-31 21:29:14 +02:00
|
|
|
max_data_file_length=
|
|
|
|
(share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
|
|
|
|
(((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
|
2002-10-08 17:58:43 +03:00
|
|
|
(mi_safe_mul(share->base.pack_reclength,
|
2000-07-31 21:29:14 +02:00
|
|
|
(ulonglong) 1 << (share->base.rec_reflength*8))-1);
|
|
|
|
max_key_file_length=
|
2001-10-02 05:53:00 +03:00
|
|
|
mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
|
2000-07-31 21:29:14 +02:00
|
|
|
((ulonglong) 1 << (share->base.key_reflength*8))-1);
|
|
|
|
#if SIZEOF_OFF_T == 4
|
|
|
|
set_if_smaller(max_data_file_length, INT_MAX32);
|
|
|
|
set_if_smaller(max_key_file_length, INT_MAX32);
|
|
|
|
#endif
|
|
|
|
share->base.max_data_file_length=(my_off_t) max_data_file_length;
|
|
|
|
share->base.max_key_file_length=(my_off_t) max_key_file_length;
|
|
|
|
|
|
|
|
if (share->options & HA_OPTION_COMPRESS_RECORD)
|
|
|
|
share->base.max_key_length+=2; /* For safety */
|
|
|
|
|
2008-02-12 15:12:45 +04:00
|
|
|
/* Add space for node pointer */
|
|
|
|
share->base.max_key_length+= share->base.key_reflength;
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
if (!my_multi_malloc(MY_WME,
|
|
|
|
&share,sizeof(*share),
|
|
|
|
&share->state.rec_per_key_part,sizeof(long)*key_parts,
|
|
|
|
&share->keyinfo,keys*sizeof(MI_KEYDEF),
|
|
|
|
&share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
|
|
|
|
&share->keyparts,
|
|
|
|
(key_parts+unique_key_parts+keys+uniques) *
|
2002-04-25 15:10:29 +05:00
|
|
|
sizeof(HA_KEYSEG),
|
2000-07-31 21:29:14 +02:00
|
|
|
&share->rec,
|
|
|
|
(share->base.fields+1)*sizeof(MI_COLUMNDEF),
|
|
|
|
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
|
2001-05-31 14:07:17 +03:00
|
|
|
&share->unique_file_name,strlen(name_buff)+1,
|
|
|
|
&share->index_file_name,strlen(index_name)+1,
|
|
|
|
&share->data_file_name,strlen(data_name)+1,
|
2000-07-31 21:29:14 +02:00
|
|
|
&share->state.key_root,keys*sizeof(my_off_t),
|
|
|
|
&share->state.key_del,
|
2006-05-03 15:59:17 +03:00
|
|
|
(share->state.header.max_block_size_index*sizeof(my_off_t)),
|
2000-07-31 21:29:14 +02:00
|
|
|
#ifdef THREAD
|
2009-12-04 18:26:15 -07:00
|
|
|
&share->key_root_lock, sizeof(mysql_rwlock_t)*keys,
|
2000-07-31 21:29:14 +02:00
|
|
|
#endif
|
2009-12-04 18:26:15 -07:00
|
|
|
&share->mmap_lock, sizeof(mysql_rwlock_t),
|
2000-07-31 21:29:14 +02:00
|
|
|
NullS))
|
|
|
|
goto err;
|
|
|
|
errpos=4;
|
|
|
|
*share=share_buff;
|
|
|
|
memcpy((char*) share->state.rec_per_key_part,
|
|
|
|
(char*) rec_per_key_part, sizeof(long)*key_parts);
|
|
|
|
memcpy((char*) share->state.key_root,
|
|
|
|
(char*) key_root, sizeof(my_off_t)*keys);
|
|
|
|
memcpy((char*) share->state.key_del,
|
|
|
|
(char*) key_del, (sizeof(my_off_t) *
|
2006-05-03 15:59:17 +03:00
|
|
|
share->state.header.max_block_size_index));
|
2001-05-31 14:07:17 +03:00
|
|
|
strmov(share->unique_file_name, name_buff);
|
2003-11-18 13:47:27 +02:00
|
|
|
share->unique_name_length= strlen(name_buff);
|
2001-05-31 14:07:17 +03:00
|
|
|
strmov(share->index_file_name, index_name);
|
|
|
|
strmov(share->data_file_name, data_name);
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
share->blocksize=min(IO_SIZE,myisam_block_size);
|
|
|
|
{
|
2002-04-25 15:10:29 +05:00
|
|
|
HA_KEYSEG *pos=share->keyparts;
|
2009-01-26 10:35:15 +04:00
|
|
|
uint32 ftkey_nr= 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
for (i=0 ; i < keys ; i++)
|
|
|
|
{
|
2004-12-31 03:47:56 +02:00
|
|
|
share->keyinfo[i].share= share;
|
2000-07-31 21:29:14 +02:00
|
|
|
disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
|
2003-03-17 15:05:04 +02:00
|
|
|
disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
|
2003-03-16 19:17:54 +02:00
|
|
|
end_pos);
|
2003-01-21 19:24:34 +01:00
|
|
|
if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
|
|
|
|
have_rtree=1;
|
2000-07-31 21:29:14 +02:00
|
|
|
set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
|
|
|
|
share->keyinfo[i].seg=pos;
|
|
|
|
for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
|
|
|
|
{
|
|
|
|
disk_pos=mi_keyseg_read(disk_pos, pos);
|
2007-01-16 18:05:37 +04:00
|
|
|
if (pos->flag & HA_BLOB_PART &&
|
|
|
|
! (share->options & (HA_OPTION_COMPRESS_RECORD |
|
|
|
|
HA_OPTION_PACK_RECORD)))
|
|
|
|
{
|
|
|
|
my_errno= HA_ERR_CRASHED;
|
|
|
|
goto err;
|
|
|
|
}
|
2004-12-18 05:19:21 +02:00
|
|
|
if (pos->type == HA_KEYTYPE_TEXT ||
|
|
|
|
pos->type == HA_KEYTYPE_VARTEXT1 ||
|
|
|
|
pos->type == HA_KEYTYPE_VARTEXT2)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
if (!pos->language)
|
|
|
|
pos->charset=default_charset_info;
|
|
|
|
else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
|
|
|
|
{
|
|
|
|
my_errno=HA_ERR_UNKNOWN_CHARSET;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
2006-10-03 14:11:57 +05:00
|
|
|
else if (pos->type == HA_KEYTYPE_BINARY)
|
|
|
|
pos->charset= &my_charset_bin;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2002-02-20 14:11:21 +04:00
|
|
|
if (share->keyinfo[i].flag & HA_SPATIAL)
|
|
|
|
{
|
2004-03-12 18:51:03 +04:00
|
|
|
#ifdef HAVE_SPATIAL
|
2002-02-20 14:11:21 +04:00
|
|
|
uint sp_segs=SPDIMS*2;
|
|
|
|
share->keyinfo[i].seg=pos-sp_segs;
|
|
|
|
share->keyinfo[i].keysegs--;
|
2004-03-12 18:51:03 +04:00
|
|
|
#else
|
|
|
|
my_errno=HA_ERR_UNSUPPORTED;
|
|
|
|
goto err;
|
|
|
|
#endif
|
2003-01-21 19:24:34 +01:00
|
|
|
}
|
|
|
|
else if (share->keyinfo[i].flag & HA_FULLTEXT)
|
2000-09-26 00:33:25 +03:00
|
|
|
{
|
2003-01-21 19:24:34 +01:00
|
|
|
if (!fulltext_keys)
|
|
|
|
{ /* 4.0 compatibility code, to be removed in 5.0 */
|
|
|
|
share->keyinfo[i].seg=pos-FT_SEGS;
|
|
|
|
share->keyinfo[i].keysegs-=FT_SEGS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-12-15 00:51:37 +02:00
|
|
|
uint k;
|
2003-01-21 19:24:34 +01:00
|
|
|
share->keyinfo[i].seg=pos;
|
2006-12-15 00:51:37 +02:00
|
|
|
for (k=0; k < FT_SEGS; k++)
|
2003-01-21 19:24:34 +01:00
|
|
|
{
|
2006-12-15 00:51:37 +02:00
|
|
|
*pos= ft_keysegs[k];
|
2003-01-21 19:24:34 +01:00
|
|
|
pos[0].language= pos[-1].language;
|
2003-01-27 17:27:21 +01:00
|
|
|
if (!(pos[0].charset= pos[-1].charset))
|
|
|
|
{
|
|
|
|
my_errno=HA_ERR_CRASHED;
|
|
|
|
goto err;
|
|
|
|
}
|
2003-01-21 19:24:34 +01:00
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!share->ft2_keyinfo.seg)
|
|
|
|
{
|
|
|
|
memcpy(& share->ft2_keyinfo, & share->keyinfo[i], sizeof(MI_KEYDEF));
|
|
|
|
share->ft2_keyinfo.keysegs=1;
|
|
|
|
share->ft2_keyinfo.flag=0;
|
|
|
|
share->ft2_keyinfo.keylength=
|
|
|
|
share->ft2_keyinfo.minlength=
|
|
|
|
share->ft2_keyinfo.maxlength=HA_FT_WLEN+share->base.rec_reflength;
|
|
|
|
share->ft2_keyinfo.seg=pos-1;
|
|
|
|
share->ft2_keyinfo.end=pos;
|
|
|
|
setup_key_functions(& share->ft2_keyinfo);
|
|
|
|
}
|
2009-01-26 10:35:15 +04:00
|
|
|
share->keyinfo[i].ftkey_nr= ftkey_nr++;
|
2000-09-26 00:33:25 +03:00
|
|
|
}
|
2003-01-21 19:24:34 +01:00
|
|
|
setup_key_functions(share->keyinfo+i);
|
2000-07-31 21:29:14 +02:00
|
|
|
share->keyinfo[i].end=pos;
|
|
|
|
pos->type=HA_KEYTYPE_END; /* End */
|
|
|
|
pos->length=share->base.rec_reflength;
|
|
|
|
pos->null_bit=0;
|
2001-11-07 00:08:57 +02:00
|
|
|
pos->flag=0; /* For purify */
|
2000-07-31 21:29:14 +02:00
|
|
|
pos++;
|
|
|
|
}
|
2009-01-26 10:35:15 +04:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
for (i=0 ; i < uniques ; i++)
|
|
|
|
{
|
|
|
|
disk_pos=mi_uniquedef_read(disk_pos, &share->uniqueinfo[i]);
|
2003-03-11 21:25:17 +02:00
|
|
|
disk_pos_assert(disk_pos + share->uniqueinfo[i].keysegs *
|
2003-03-17 15:05:04 +02:00
|
|
|
HA_KEYSEG_SIZE, end_pos);
|
2000-07-31 21:29:14 +02:00
|
|
|
share->uniqueinfo[i].seg=pos;
|
|
|
|
for (j=0 ; j < share->uniqueinfo[i].keysegs; j++,pos++)
|
|
|
|
{
|
|
|
|
disk_pos=mi_keyseg_read(disk_pos, pos);
|
2004-12-18 05:19:21 +02:00
|
|
|
if (pos->type == HA_KEYTYPE_TEXT ||
|
|
|
|
pos->type == HA_KEYTYPE_VARTEXT1 ||
|
|
|
|
pos->type == HA_KEYTYPE_VARTEXT2)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
if (!pos->language)
|
|
|
|
pos->charset=default_charset_info;
|
|
|
|
else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
|
|
|
|
{
|
|
|
|
my_errno=HA_ERR_UNKNOWN_CHARSET;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
share->uniqueinfo[i].end=pos;
|
|
|
|
pos->type=HA_KEYTYPE_END; /* End */
|
|
|
|
pos->null_bit=0;
|
2001-11-07 00:08:57 +02:00
|
|
|
pos->flag=0;
|
2000-07-31 21:29:14 +02:00
|
|
|
pos++;
|
|
|
|
}
|
2009-01-26 10:35:15 +04:00
|
|
|
share->ftkeys= ftkey_nr;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2003-03-11 21:25:17 +02:00
|
|
|
disk_pos_assert(disk_pos + share->base.fields *MI_COLUMNDEF_SIZE, end_pos);
|
2000-07-31 21:29:14 +02:00
|
|
|
for (i=j=offset=0 ; i < share->base.fields ; i++)
|
|
|
|
{
|
|
|
|
disk_pos=mi_recinfo_read(disk_pos,&share->rec[i]);
|
|
|
|
share->rec[i].pack_type=0;
|
|
|
|
share->rec[i].huff_tree=0;
|
|
|
|
share->rec[i].offset=offset;
|
|
|
|
if (share->rec[i].type == (int) FIELD_BLOB)
|
|
|
|
{
|
|
|
|
share->blobs[j].pack_length=
|
2007-10-11 18:07:40 +03:00
|
|
|
share->rec[i].length-portable_sizeof_char_ptr;
|
2000-07-31 21:29:14 +02:00
|
|
|
share->blobs[j].offset=offset;
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
offset+=share->rec[i].length;
|
|
|
|
}
|
|
|
|
share->rec[i].type=(int) FIELD_LAST; /* End marker */
|
2007-01-22 16:34:58 +04:00
|
|
|
if (offset > share->base.reclength)
|
|
|
|
{
|
|
|
|
/* purecov: begin inspected */
|
|
|
|
my_errno= HA_ERR_CRASHED;
|
|
|
|
goto err;
|
|
|
|
/* purecov: end */
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
if (! lock_error)
|
|
|
|
{
|
2009-11-24 16:54:59 +03:00
|
|
|
(void) my_lock(kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
|
2000-07-31 21:29:14 +02:00
|
|
|
lock_error=1; /* Database unlocked */
|
|
|
|
}
|
|
|
|
|
2008-08-22 17:31:53 +05:00
|
|
|
if (mi_open_datafile(&info, share, name, -1))
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
|
|
|
errpos=5;
|
|
|
|
|
|
|
|
share->kfile=kfile;
|
|
|
|
share->this_process=(ulong) getpid();
|
|
|
|
share->last_process= share->state.process;
|
|
|
|
share->base.key_parts=key_parts;
|
|
|
|
share->base.all_key_parts=key_parts+unique_key_parts;
|
|
|
|
if (!(share->last_version=share->state.version))
|
|
|
|
share->last_version=1; /* Safety */
|
|
|
|
share->rec_reflength=share->base.rec_reflength; /* May be changed */
|
|
|
|
share->base.margin_key_file_length=(share->base.max_key_file_length -
|
|
|
|
(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)
|
|
|
|
{
|
|
|
|
share->data_file_type = COMPRESSED_RECORD;
|
|
|
|
share->options|= HA_OPTION_READ_ONLY_DATA;
|
|
|
|
info.s=share;
|
|
|
|
if (_mi_read_pack_info(&info,
|
|
|
|
(pbool)
|
|
|
|
test(!(share->options &
|
|
|
|
(HA_OPTION_PACK_RECORD |
|
|
|
|
HA_OPTION_TEMP_COMPRESS_RECORD)))))
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else if (share->options & HA_OPTION_PACK_RECORD)
|
|
|
|
share->data_file_type = DYNAMIC_RECORD;
|
2007-08-13 16:11:25 +03:00
|
|
|
my_afree(disk_cache);
|
2001-11-22 13:50:50 +02:00
|
|
|
mi_setup_functions(share);
|
2006-08-03 21:28:15 +04:00
|
|
|
share->is_log_table= FALSE;
|
2000-07-31 21:29:14 +02:00
|
|
|
#ifdef THREAD
|
|
|
|
thr_lock_init(&share->lock);
|
2009-12-04 18:26:15 -07:00
|
|
|
mysql_mutex_init(mi_key_mutex_MYISAM_SHARE_intern_lock,
|
|
|
|
&share->intern_lock, MY_MUTEX_INIT_FAST);
|
2000-07-31 21:29:14 +02:00
|
|
|
for (i=0; i<keys; i++)
|
2009-12-04 18:26:15 -07:00
|
|
|
mysql_rwlock_init(mi_key_rwlock_MYISAM_SHARE_key_root_lock,
|
|
|
|
&share->key_root_lock[i]);
|
|
|
|
mysql_rwlock_init(mi_key_rwlock_MYISAM_SHARE_mmap_lock, &share->mmap_lock);
|
2000-07-31 21:29:14 +02:00
|
|
|
if (!thr_lock_inited)
|
|
|
|
{
|
|
|
|
/* Probably a single threaded program; Don't use concurrent inserts */
|
|
|
|
myisam_concurrent_insert=0;
|
|
|
|
}
|
|
|
|
else if (myisam_concurrent_insert)
|
|
|
|
{
|
|
|
|
share->concurrent_insert=
|
|
|
|
((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
|
|
|
|
HA_OPTION_COMPRESS_RECORD |
|
|
|
|
HA_OPTION_TEMP_COMPRESS_RECORD)) ||
|
2002-02-20 14:11:21 +04:00
|
|
|
(open_flags & HA_OPEN_TMP_TABLE) ||
|
|
|
|
have_rtree) ? 0 : 1;
|
2000-07-31 21:29:14 +02:00
|
|
|
if (share->concurrent_insert)
|
|
|
|
{
|
|
|
|
share->lock.get_status=mi_get_status;
|
|
|
|
share->lock.copy_status=mi_copy_status;
|
|
|
|
share->lock.update_status=mi_update_status;
|
2006-12-05 18:44:14 +04:00
|
|
|
share->lock.restore_status= mi_restore_status;
|
2000-07-31 21:29:14 +02:00
|
|
|
share->lock.check_status=mi_check_status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2007-02-22 09:12:07 +01:00
|
|
|
/*
|
|
|
|
Memory mapping can only be requested after initializing intern_lock.
|
|
|
|
*/
|
|
|
|
if (open_flags & HA_OPEN_MMAP)
|
|
|
|
{
|
|
|
|
info.s= share;
|
|
|
|
mi_extra(&info, HA_EXTRA_MMAP, 0);
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
share= old_info->s;
|
|
|
|
if (mode == O_RDWR && share->mode == O_RDONLY)
|
|
|
|
{
|
|
|
|
my_errno=EACCES; /* Can't open in write mode */
|
|
|
|
goto err;
|
|
|
|
}
|
2008-08-22 17:31:53 +05:00
|
|
|
if (mi_open_datafile(&info, share, name, old_info->dfile))
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
|
|
|
errpos=5;
|
2003-02-19 21:14:50 +04:00
|
|
|
have_rtree= old_info->rtree_recursion_state != NULL;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* alloc and set up private structure parts */
|
|
|
|
if (!my_multi_malloc(MY_WME,
|
|
|
|
&m_info,sizeof(MI_INFO),
|
|
|
|
&info.blobs,sizeof(MI_BLOB)*share->base.blobs,
|
|
|
|
&info.buff,(share->base.max_key_block_length*2+
|
|
|
|
share->base.max_key_length),
|
|
|
|
&info.lastkey,share->base.max_key_length*3+1,
|
2003-11-04 17:58:18 +04:00
|
|
|
&info.first_mbr_key, share->base.max_key_length,
|
2005-06-09 09:00:51 -05:00
|
|
|
&info.filename,strlen(name)+1,
|
2003-02-19 21:14:50 +04:00
|
|
|
&info.rtree_recursion_state,have_rtree ? 1024 : 0,
|
2000-07-31 21:29:14 +02:00
|
|
|
NullS))
|
|
|
|
goto err;
|
|
|
|
errpos=6;
|
2003-10-02 20:22:29 +02:00
|
|
|
|
|
|
|
if (!have_rtree)
|
2003-02-19 21:14:50 +04:00
|
|
|
info.rtree_recursion_state= NULL;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2005-06-09 09:00:51 -05:00
|
|
|
strmov(info.filename,name);
|
2000-07-31 21:29:14 +02:00
|
|
|
memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
|
|
|
|
info.lastkey2=info.lastkey+share->base.max_key_length;
|
|
|
|
|
|
|
|
info.s=share;
|
|
|
|
info.lastpos= HA_OFFSET_ERROR;
|
|
|
|
info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND);
|
|
|
|
info.opt_flag=READ_CHECK_USED;
|
|
|
|
info.this_unique= (ulong) info.dfile; /* Uniq number in process */
|
|
|
|
if (share->data_file_type == COMPRESSED_RECORD)
|
|
|
|
info.this_unique= share->state.unique;
|
2000-11-16 03:58:58 +02:00
|
|
|
info.this_loop=0; /* Update counter */
|
2000-07-31 21:29:14 +02:00
|
|
|
info.last_unique= share->state.unique;
|
2000-11-16 03:58:58 +02:00
|
|
|
info.last_loop= share->state.update_count;
|
2000-07-31 21:29:14 +02:00
|
|
|
if (mode == O_RDONLY)
|
|
|
|
share->options|=HA_OPTION_READ_ONLY_DATA;
|
|
|
|
info.lock_type=F_UNLCK;
|
|
|
|
info.quick_mode=0;
|
2001-07-02 21:18:57 +02:00
|
|
|
info.bulk_insert=0;
|
2003-10-02 20:22:29 +02:00
|
|
|
info.ft1_to_ft2=0;
|
2000-07-31 21:29:14 +02:00
|
|
|
info.errkey= -1;
|
|
|
|
info.page_changed=1;
|
2009-12-04 18:26:15 -07:00
|
|
|
mysql_mutex_lock(&share->intern_lock);
|
2000-07-31 21:29:14 +02:00
|
|
|
info.read_record=share->read_record;
|
|
|
|
share->reopen++;
|
|
|
|
share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
|
|
|
|
if (share->options & HA_OPTION_READ_ONLY_DATA)
|
|
|
|
{
|
|
|
|
info.lock_type=F_RDLCK;
|
|
|
|
share->r_locks++;
|
2002-06-17 12:34:19 +03:00
|
|
|
share->tot_locks++;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
2000-09-26 00:33:25 +03:00
|
|
|
if ((open_flags & HA_OPEN_TMP_TABLE) ||
|
2000-07-31 21:29:14 +02:00
|
|
|
(share->options & HA_OPTION_TMP_TABLE))
|
|
|
|
{
|
|
|
|
share->temporary=share->delay_key_write=1;
|
|
|
|
share->write_flag=MYF(MY_NABP);
|
|
|
|
share->w_locks++; /* We don't have to update status */
|
2002-06-17 12:34:19 +03:00
|
|
|
share->tot_locks++;
|
2000-07-31 21:29:14 +02:00
|
|
|
info.lock_type=F_WRLCK;
|
|
|
|
}
|
2000-09-26 00:33:25 +03:00
|
|
|
if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
|
2000-07-31 21:29:14 +02:00
|
|
|
(share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
|
|
|
|
myisam_delay_key_write)
|
|
|
|
share->delay_key_write=1;
|
|
|
|
info.state= &share->state.state; /* Change global values by default */
|
2009-12-04 18:26:15 -07:00
|
|
|
mysql_mutex_unlock(&share->intern_lock);
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
/* Allocate buffer for one record */
|
|
|
|
|
2002-07-09 22:42:44 +02:00
|
|
|
/* prerequisites: bzero(info) && info->s=share; are met. */
|
2002-07-26 14:42:51 +02:00
|
|
|
if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
|
2000-07-31 21:29:14 +02:00
|
|
|
goto err;
|
2002-07-26 14:42:51 +02:00
|
|
|
bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
*m_info=info;
|
|
|
|
#ifdef THREAD
|
|
|
|
thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
|
|
|
|
#endif
|
|
|
|
m_info->open_list.data=(void*) m_info;
|
|
|
|
myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
|
|
|
|
|
2009-12-04 18:26:15 -07:00
|
|
|
mysql_mutex_unlock(&THR_LOCK_myisam);
|
2010-03-25 15:18:14 +04:00
|
|
|
|
|
|
|
bzero(info.buff, share->base.max_key_block_length * 2);
|
|
|
|
|
2000-09-14 02:39:07 +03:00
|
|
|
if (myisam_log_file >= 0)
|
|
|
|
{
|
2001-05-31 14:07:17 +03:00
|
|
|
intern_filename(name_buff,share->index_file_name);
|
2007-08-13 16:11:25 +03:00
|
|
|
_myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
|
2000-09-14 02:39:07 +03:00
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
DBUG_RETURN(m_info);
|
|
|
|
|
|
|
|
err:
|
|
|
|
save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
|
2004-12-23 20:11:38 +01:00
|
|
|
if ((save_errno == HA_ERR_CRASHED) ||
|
|
|
|
(save_errno == HA_ERR_CRASHED_ON_USAGE) ||
|
|
|
|
(save_errno == HA_ERR_CRASHED_ON_REPAIR))
|
|
|
|
mi_report_error(save_errno, name);
|
2000-07-31 21:29:14 +02:00
|
|
|
switch (errpos) {
|
|
|
|
case 6:
|
Bug#34043: Server loops excessively in _checkchunk() when safemalloc is enabled
Essentially, the problem is that safemalloc is excruciatingly
slow as it checks all allocated blocks for overrun at each
memory management primitive, yielding a almost exponential
slowdown for the memory management functions (malloc, realloc,
free). The overrun check basically consists of verifying some
bytes of a block for certain magic keys, which catches some
simple forms of overrun. Another minor problem is violation
of aliasing rules and that its own internal list of blocks
is prone to corruption.
Another issue with safemalloc is rather the maintenance cost
as the tool has a significant impact on the server code.
Given the magnitude of memory debuggers available nowadays,
especially those that are provided with the platform malloc
implementation, maintenance of a in-house and largely obsolete
memory debugger becomes a burden that is not worth the effort
due to its slowness and lack of support for detecting more
common forms of heap corruption.
Since there are third-party tools that can provide the same
functionality at a lower or comparable performance cost, the
solution is to simply remove safemalloc. Third-party tools
can provide the same functionality at a lower or comparable
performance cost.
The removal of safemalloc also allows a simplification of the
malloc wrappers, removing quite a bit of kludge: redefinition
of my_malloc, my_free and the removal of the unused second
argument of my_free. Since free() always check whether the
supplied pointer is null, redudant checks are also removed.
Also, this patch adds unit testing for my_malloc and moves
my_realloc implementation into the same file as the other
memory allocation primitives.
2010-07-08 18:20:08 -03:00
|
|
|
my_free(m_info);
|
2000-07-31 21:29:14 +02:00
|
|
|
/* fall through */
|
|
|
|
case 5:
|
2009-12-04 18:26:15 -07:00
|
|
|
(void) mysql_file_close(info.dfile, MYF(0));
|
2000-07-31 21:29:14 +02:00
|
|
|
if (old_info)
|
|
|
|
break; /* Don't remove open table */
|
|
|
|
/* fall through */
|
|
|
|
case 4:
|
Bug#34043: Server loops excessively in _checkchunk() when safemalloc is enabled
Essentially, the problem is that safemalloc is excruciatingly
slow as it checks all allocated blocks for overrun at each
memory management primitive, yielding a almost exponential
slowdown for the memory management functions (malloc, realloc,
free). The overrun check basically consists of verifying some
bytes of a block for certain magic keys, which catches some
simple forms of overrun. Another minor problem is violation
of aliasing rules and that its own internal list of blocks
is prone to corruption.
Another issue with safemalloc is rather the maintenance cost
as the tool has a significant impact on the server code.
Given the magnitude of memory debuggers available nowadays,
especially those that are provided with the platform malloc
implementation, maintenance of a in-house and largely obsolete
memory debugger becomes a burden that is not worth the effort
due to its slowness and lack of support for detecting more
common forms of heap corruption.
Since there are third-party tools that can provide the same
functionality at a lower or comparable performance cost, the
solution is to simply remove safemalloc. Third-party tools
can provide the same functionality at a lower or comparable
performance cost.
The removal of safemalloc also allows a simplification of the
malloc wrappers, removing quite a bit of kludge: redefinition
of my_malloc, my_free and the removal of the unused second
argument of my_free. Since free() always check whether the
supplied pointer is null, redudant checks are also removed.
Also, this patch adds unit testing for my_malloc and moves
my_realloc implementation into the same file as the other
memory allocation primitives.
2010-07-08 18:20:08 -03:00
|
|
|
my_free(share);
|
2000-07-31 21:29:14 +02:00
|
|
|
/* fall through */
|
|
|
|
case 3:
|
|
|
|
if (! lock_error)
|
2009-11-24 16:54:59 +03:00
|
|
|
(void) my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE));
|
2000-07-31 21:29:14 +02:00
|
|
|
/* fall through */
|
|
|
|
case 2:
|
2007-08-13 16:11:25 +03:00
|
|
|
my_afree(disk_cache);
|
2000-07-31 21:29:14 +02:00
|
|
|
/* fall through */
|
|
|
|
case 1:
|
2009-12-04 18:26:15 -07:00
|
|
|
(void) mysql_file_close(kfile, MYF(0));
|
2000-07-31 21:29:14 +02:00
|
|
|
/* fall through */
|
|
|
|
case 0:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-12-04 18:26:15 -07:00
|
|
|
mysql_mutex_unlock(&THR_LOCK_myisam);
|
2000-07-31 21:29:14 +02:00
|
|
|
my_errno=save_errno;
|
|
|
|
DBUG_RETURN (NULL);
|
|
|
|
} /* mi_open */
|
|
|
|
|
2003-01-09 02:19:14 +02:00
|
|
|
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 12:59:39 +03:00
|
|
|
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
|
2002-07-14 13:51:03 +02:00
|
|
|
{
|
|
|
|
uint extra;
|
2009-08-28 17:51:31 +02:00
|
|
|
uint32 UNINIT_VAR(old_length);
|
2003-01-09 02:19:14 +02:00
|
|
|
LINT_INIT(old_length);
|
2002-07-14 13:51:03 +02:00
|
|
|
|
2003-01-09 02:19:14 +02:00
|
|
|
if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
|
2002-07-14 13:51:03 +02:00
|
|
|
{
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 12:59:39 +03:00
|
|
|
uchar *newptr = *buf;
|
2002-07-14 13:51:03 +02:00
|
|
|
|
|
|
|
/* to simplify initial init of info->rec_buf in mi_open and mi_extra */
|
2002-07-24 19:55:08 +03:00
|
|
|
if (length == (ulong) -1)
|
2003-01-09 02:19:14 +02:00
|
|
|
{
|
2007-11-07 12:55:28 +04:00
|
|
|
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
|
|
|
|
length= max(info->s->base.pack_reclength, info->s->max_pack_length);
|
|
|
|
else
|
|
|
|
length= info->s->base.pack_reclength;
|
|
|
|
length= max(length, info->s->base.max_key_length);
|
2003-01-09 02:19:14 +02:00
|
|
|
/* Avoid unnecessary realloc */
|
|
|
|
if (newptr && length == old_length)
|
|
|
|
return newptr;
|
|
|
|
}
|
2002-07-14 13:51:03 +02:00
|
|
|
|
|
|
|
extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
|
2002-07-24 19:55:08 +03:00
|
|
|
ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
|
|
|
|
MI_REC_BUFF_OFFSET : 0);
|
2002-07-14 13:51:03 +02:00
|
|
|
if (extra && newptr)
|
2003-01-09 02:19:14 +02:00
|
|
|
newptr-= MI_REC_BUFF_OFFSET;
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 12:59:39 +03:00
|
|
|
if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
|
2002-07-26 14:42:51 +02:00
|
|
|
MYF(MY_ALLOW_ZERO_PTR))))
|
|
|
|
return newptr;
|
2003-01-09 02:19:14 +02:00
|
|
|
*((uint32 *) newptr)= (uint32) length;
|
2002-07-24 19:55:08 +03:00
|
|
|
*buf= newptr+(extra ? MI_REC_BUFF_OFFSET : 0);
|
2002-07-14 13:51:03 +02:00
|
|
|
}
|
|
|
|
return *buf;
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2002-07-24 19:55:08 +03:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
ulonglong mi_safe_mul(ulonglong a, ulonglong b)
|
|
|
|
{
|
|
|
|
ulonglong max_val= ~ (ulonglong) 0; /* my_off_t is unsigned */
|
|
|
|
|
|
|
|
if (!a || max_val / a < b)
|
|
|
|
return max_val;
|
|
|
|
return a*b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set up functions in structs */
|
|
|
|
|
2001-11-22 13:50:50 +02:00
|
|
|
void mi_setup_functions(register MYISAM_SHARE *share)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
if (share->options & HA_OPTION_COMPRESS_RECORD)
|
|
|
|
{
|
|
|
|
share->read_record=_mi_read_pack_record;
|
|
|
|
share->read_rnd=_mi_read_rnd_pack_record;
|
|
|
|
if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
|
|
|
|
share->calc_checksum=0; /* No checksum */
|
|
|
|
else if (share->options & HA_OPTION_PACK_RECORD)
|
|
|
|
share->calc_checksum= mi_checksum;
|
|
|
|
else
|
|
|
|
share->calc_checksum= mi_static_checksum;
|
|
|
|
}
|
|
|
|
else if (share->options & HA_OPTION_PACK_RECORD)
|
|
|
|
{
|
|
|
|
share->read_record=_mi_read_dynamic_record;
|
|
|
|
share->read_rnd=_mi_read_rnd_dynamic_record;
|
|
|
|
share->delete_record=_mi_delete_dynamic_record;
|
|
|
|
share->compare_record=_mi_cmp_dynamic_record;
|
|
|
|
share->compare_unique=_mi_cmp_dynamic_unique;
|
|
|
|
share->calc_checksum= mi_checksum;
|
|
|
|
|
2003-08-28 06:08:17 +03:00
|
|
|
/* add bits used to pack data to pack_reclength for faster allocation */
|
|
|
|
share->base.pack_reclength+= share->base.pack_bits;
|
2000-07-31 21:29:14 +02:00
|
|
|
if (share->base.blobs)
|
|
|
|
{
|
|
|
|
share->update_record=_mi_update_blob_record;
|
|
|
|
share->write_record=_mi_write_blob_record;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
share->write_record=_mi_write_dynamic_record;
|
|
|
|
share->update_record=_mi_update_dynamic_record;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
share->read_record=_mi_read_static_record;
|
|
|
|
share->read_rnd=_mi_read_rnd_static_record;
|
|
|
|
share->delete_record=_mi_delete_static_record;
|
|
|
|
share->compare_record=_mi_cmp_static_record;
|
|
|
|
share->update_record=_mi_update_static_record;
|
|
|
|
share->write_record=_mi_write_static_record;
|
|
|
|
share->compare_unique=_mi_cmp_static_unique;
|
|
|
|
share->calc_checksum= mi_static_checksum;
|
|
|
|
}
|
2005-12-01 13:34:48 +01:00
|
|
|
share->file_read= mi_nommap_pread;
|
|
|
|
share->file_write= mi_nommap_pwrite;
|
2000-07-31 21:29:14 +02:00
|
|
|
if (!(share->options & HA_OPTION_CHECKSUM))
|
|
|
|
share->calc_checksum=0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void setup_key_functions(register MI_KEYDEF *keyinfo)
|
|
|
|
{
|
2002-02-20 14:11:21 +04:00
|
|
|
if (keyinfo->key_alg == HA_KEY_ALG_RTREE)
|
|
|
|
{
|
2004-03-12 18:51:03 +04:00
|
|
|
#ifdef HAVE_RTREE_KEYS
|
2002-02-20 14:11:21 +04:00
|
|
|
keyinfo->ck_insert = rtree_insert;
|
|
|
|
keyinfo->ck_delete = rtree_delete;
|
2004-03-15 12:31:21 +04:00
|
|
|
#else
|
|
|
|
DBUG_ASSERT(0); /* mi_open should check it never happens */
|
2004-03-12 18:51:03 +04:00
|
|
|
#endif
|
2002-02-20 14:11:21 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
keyinfo->ck_insert = _mi_ck_write;
|
|
|
|
keyinfo->ck_delete = _mi_ck_delete;
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
if (keyinfo->flag & HA_BINARY_PACK_KEY)
|
|
|
|
{ /* Simple prefix compression */
|
|
|
|
keyinfo->bin_search=_mi_seq_search;
|
|
|
|
keyinfo->get_key=_mi_get_binary_pack_key;
|
|
|
|
keyinfo->pack_key=_mi_calc_bin_pack_key_length;
|
|
|
|
keyinfo->store_key=_mi_store_bin_pack_key;
|
|
|
|
}
|
|
|
|
else if (keyinfo->flag & HA_VAR_LENGTH_KEY)
|
|
|
|
{
|
|
|
|
keyinfo->get_key= _mi_get_pack_key;
|
|
|
|
if (keyinfo->seg[0].flag & HA_PACK_KEY)
|
|
|
|
{ /* Prefix compression */
|
2007-12-18 12:29:50 +01:00
|
|
|
/*
|
|
|
|
_mi_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 _mi_seq_search() for the search.
|
|
|
|
*/
|
2002-10-09 15:40:57 +05:00
|
|
|
if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) ||
|
2007-12-18 12:29:50 +01:00
|
|
|
(keyinfo->seg->flag & HA_NULL_PART) ||
|
|
|
|
(keyinfo->seg->charset->mbminlen > 1))
|
2001-04-11 13:04:03 +02:00
|
|
|
keyinfo->bin_search=_mi_seq_search;
|
|
|
|
else
|
|
|
|
keyinfo->bin_search=_mi_prefix_search;
|
2000-07-31 21:29:14 +02:00
|
|
|
keyinfo->pack_key=_mi_calc_var_pack_key_length;
|
|
|
|
keyinfo->store_key=_mi_store_var_pack_key;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-04-11 13:04:03 +02:00
|
|
|
keyinfo->bin_search=_mi_seq_search;
|
2000-07-31 21:29:14 +02:00
|
|
|
keyinfo->pack_key=_mi_calc_var_key_length; /* Variable length key */
|
|
|
|
keyinfo->store_key=_mi_store_static_key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
keyinfo->bin_search=_mi_bin_search;
|
|
|
|
keyinfo->get_key=_mi_get_static_key;
|
|
|
|
keyinfo->pack_key=_mi_calc_static_key_length;
|
|
|
|
keyinfo->store_key=_mi_store_static_key;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-01-21 19:24:34 +01:00
|
|
|
/*
|
|
|
|
Function to save and store the header in the index file (.MYI)
|
|
|
|
*/
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
|
|
|
|
{
|
|
|
|
uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
|
|
|
|
uchar *ptr=buff;
|
|
|
|
uint i, keys= (uint) state->header.keys,
|
2006-05-03 15:59:17 +03:00
|
|
|
key_blocks=state->header.max_block_size_index;
|
2003-09-05 06:42:55 +03:00
|
|
|
DBUG_ENTER("mi_state_info_write");
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2010-07-23 17:17:55 -03:00
|
|
|
memcpy(ptr, &state->header, sizeof(state->header));
|
2000-07-31 21:29:14 +02:00
|
|
|
ptr+=sizeof(state->header);
|
|
|
|
|
|
|
|
/* open_count must be first because of _mi_mark_file_changed ! */
|
|
|
|
mi_int2store(ptr,state->open_count); ptr +=2;
|
|
|
|
*ptr++= (uchar)state->changed; *ptr++= state->sortkey;
|
|
|
|
mi_rowstore(ptr,state->state.records); ptr +=8;
|
|
|
|
mi_rowstore(ptr,state->state.del); ptr +=8;
|
|
|
|
mi_rowstore(ptr,state->split); ptr +=8;
|
|
|
|
mi_sizestore(ptr,state->dellink); ptr +=8;
|
|
|
|
mi_sizestore(ptr,state->state.key_file_length); ptr +=8;
|
|
|
|
mi_sizestore(ptr,state->state.data_file_length); ptr +=8;
|
|
|
|
mi_sizestore(ptr,state->state.empty); ptr +=8;
|
|
|
|
mi_sizestore(ptr,state->state.key_empty); ptr +=8;
|
|
|
|
mi_int8store(ptr,state->auto_increment); ptr +=8;
|
2005-09-27 20:11:09 +02:00
|
|
|
mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
|
2000-07-31 21:29:14 +02:00
|
|
|
mi_int4store(ptr,state->process); ptr +=4;
|
|
|
|
mi_int4store(ptr,state->unique); ptr +=4;
|
|
|
|
mi_int4store(ptr,state->status); ptr +=4;
|
2000-11-16 03:58:58 +02:00
|
|
|
mi_int4store(ptr,state->update_count); ptr +=4;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
ptr+=state->state_diff_length;
|
|
|
|
|
|
|
|
for (i=0; i < keys; i++)
|
|
|
|
{
|
|
|
|
mi_sizestore(ptr,state->key_root[i]); ptr +=8;
|
|
|
|
}
|
|
|
|
for (i=0; i < key_blocks; i++)
|
|
|
|
{
|
|
|
|
mi_sizestore(ptr,state->key_del[i]); ptr +=8;
|
|
|
|
}
|
|
|
|
if (pWrite & 2) /* From isamchk */
|
|
|
|
{
|
|
|
|
uint key_parts= mi_uint2korr(state->header.key_parts);
|
|
|
|
mi_int4store(ptr,state->sec_index_changed); ptr +=4;
|
|
|
|
mi_int4store(ptr,state->sec_index_used); ptr +=4;
|
|
|
|
mi_int4store(ptr,state->version); ptr +=4;
|
|
|
|
mi_int8store(ptr,state->key_map); ptr +=8;
|
|
|
|
mi_int8store(ptr,(ulonglong) state->create_time); ptr +=8;
|
|
|
|
mi_int8store(ptr,(ulonglong) state->recover_time); ptr +=8;
|
|
|
|
mi_int8store(ptr,(ulonglong) state->check_time); ptr +=8;
|
|
|
|
mi_sizestore(ptr,state->rec_per_key_rows); ptr+=8;
|
|
|
|
for (i=0 ; i < key_parts ; i++)
|
|
|
|
{
|
|
|
|
mi_int4store(ptr,state->rec_per_key_part[i]); ptr+=4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pWrite & 1)
|
2009-12-04 18:26:15 -07:00
|
|
|
DBUG_RETURN(mysql_file_pwrite(file, buff, (size_t) (ptr-buff), 0L,
|
|
|
|
MYF(MY_NABP | MY_THREADSAFE)) != 0);
|
|
|
|
DBUG_RETURN(mysql_file_write(file, buff, (size_t) (ptr-buff),
|
|
|
|
MYF(MY_NABP)) != 0);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-23 16:47:08 +03:00
|
|
|
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
uint i,keys,key_parts,key_blocks;
|
2010-07-23 17:17:55 -03:00
|
|
|
memcpy(&state->header, ptr, sizeof(state->header));
|
2000-07-31 21:29:14 +02:00
|
|
|
ptr +=sizeof(state->header);
|
|
|
|
keys=(uint) state->header.keys;
|
|
|
|
key_parts=mi_uint2korr(state->header.key_parts);
|
2006-05-03 15:59:17 +03:00
|
|
|
key_blocks=state->header.max_block_size_index;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
|
|
|
state->open_count = mi_uint2korr(ptr); ptr +=2;
|
2007-11-21 18:52:38 +02:00
|
|
|
state->changed= *ptr++;
|
2000-07-31 21:29:14 +02:00
|
|
|
state->sortkey = (uint) *ptr++;
|
|
|
|
state->state.records= mi_rowkorr(ptr); ptr +=8;
|
|
|
|
state->state.del = mi_rowkorr(ptr); ptr +=8;
|
|
|
|
state->split = mi_rowkorr(ptr); ptr +=8;
|
|
|
|
state->dellink= mi_sizekorr(ptr); ptr +=8;
|
|
|
|
state->state.key_file_length = mi_sizekorr(ptr); ptr +=8;
|
|
|
|
state->state.data_file_length= mi_sizekorr(ptr); ptr +=8;
|
|
|
|
state->state.empty = mi_sizekorr(ptr); ptr +=8;
|
|
|
|
state->state.key_empty= mi_sizekorr(ptr); ptr +=8;
|
|
|
|
state->auto_increment=mi_uint8korr(ptr); ptr +=8;
|
2005-09-27 20:11:09 +02:00
|
|
|
state->state.checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8;
|
2000-07-31 21:29:14 +02:00
|
|
|
state->process= mi_uint4korr(ptr); ptr +=4;
|
|
|
|
state->unique = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
state->status = mi_uint4korr(ptr); ptr +=4;
|
2000-11-21 03:43:34 +02:00
|
|
|
state->update_count=mi_uint4korr(ptr); ptr +=4;
|
|
|
|
|
2003-12-12 22:26:58 +02:00
|
|
|
ptr+= state->state_diff_length;
|
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
for (i=0; i < keys; i++)
|
|
|
|
{
|
|
|
|
state->key_root[i]= mi_sizekorr(ptr); ptr +=8;
|
|
|
|
}
|
|
|
|
for (i=0; i < key_blocks; i++)
|
|
|
|
{
|
|
|
|
state->key_del[i] = mi_sizekorr(ptr); ptr +=8;
|
|
|
|
}
|
|
|
|
state->sec_index_changed = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
state->sec_index_used = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
state->version = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
state->key_map = mi_uint8korr(ptr); ptr +=8;
|
|
|
|
state->create_time = (time_t) mi_sizekorr(ptr); ptr +=8;
|
|
|
|
state->recover_time =(time_t) mi_sizekorr(ptr); ptr +=8;
|
|
|
|
state->check_time = (time_t) mi_sizekorr(ptr); ptr +=8;
|
|
|
|
state->rec_per_key_rows=mi_sizekorr(ptr); ptr +=8;
|
|
|
|
for (i=0 ; i < key_parts ; i++)
|
|
|
|
{
|
|
|
|
state->rec_per_key_part[i]= mi_uint4korr(ptr); ptr+=4;
|
|
|
|
}
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
|
|
|
|
{
|
2007-08-13 16:11:25 +03:00
|
|
|
uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2001-05-23 02:40:46 +03:00
|
|
|
if (!myisam_single_user)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2001-05-23 02:40:46 +03:00
|
|
|
if (pRead)
|
|
|
|
{
|
2009-12-04 18:26:15 -07:00
|
|
|
if (mysql_file_pread(file, buff, state->state_length, 0L, MYF(MY_NABP)))
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 12:59:39 +03:00
|
|
|
return 1;
|
2001-05-23 02:40:46 +03:00
|
|
|
}
|
2009-12-04 18:26:15 -07:00
|
|
|
else if (mysql_file_read(file, buff, state->state_length, MYF(MY_NABP)))
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 12:59:39 +03:00
|
|
|
return 1;
|
2007-08-13 16:11:25 +03:00
|
|
|
mi_state_info_read(buff, state);
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
** store and read of MI_BASE_INFO
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
uint mi_base_info_write(File file, MI_BASE_INFO *base)
|
|
|
|
{
|
|
|
|
uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
|
|
|
|
|
|
|
|
mi_sizestore(ptr,base->keystart); ptr +=8;
|
|
|
|
mi_sizestore(ptr,base->max_data_file_length); ptr +=8;
|
|
|
|
mi_sizestore(ptr,base->max_key_file_length); ptr +=8;
|
|
|
|
mi_rowstore(ptr,base->records); ptr +=8;
|
|
|
|
mi_rowstore(ptr,base->reloc); ptr +=8;
|
|
|
|
mi_int4store(ptr,base->mean_row_length); ptr +=4;
|
|
|
|
mi_int4store(ptr,base->reclength); ptr +=4;
|
|
|
|
mi_int4store(ptr,base->pack_reclength); ptr +=4;
|
|
|
|
mi_int4store(ptr,base->min_pack_length); ptr +=4;
|
|
|
|
mi_int4store(ptr,base->max_pack_length); ptr +=4;
|
|
|
|
mi_int4store(ptr,base->min_block_length); ptr +=4;
|
|
|
|
mi_int4store(ptr,base->fields); ptr +=4;
|
|
|
|
mi_int4store(ptr,base->pack_fields); ptr +=4;
|
|
|
|
*ptr++=base->rec_reflength;
|
|
|
|
*ptr++=base->key_reflength;
|
|
|
|
*ptr++=base->keys;
|
|
|
|
*ptr++=base->auto_key;
|
|
|
|
mi_int2store(ptr,base->pack_bits); ptr +=2;
|
|
|
|
mi_int2store(ptr,base->blobs); ptr +=2;
|
|
|
|
mi_int2store(ptr,base->max_key_block_length); ptr +=2;
|
|
|
|
mi_int2store(ptr,base->max_key_length); ptr +=2;
|
|
|
|
mi_int2store(ptr,base->extra_alloc_bytes); ptr +=2;
|
|
|
|
*ptr++= base->extra_alloc_procent;
|
2010-07-23 17:15:07 -03:00
|
|
|
bzero(ptr,13); ptr +=13; /* extra */
|
2009-12-04 18:26:15 -07:00
|
|
|
return mysql_file_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-23 16:47:08 +03:00
|
|
|
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
base->keystart = mi_sizekorr(ptr); ptr +=8;
|
|
|
|
base->max_data_file_length = mi_sizekorr(ptr); ptr +=8;
|
|
|
|
base->max_key_file_length = mi_sizekorr(ptr); ptr +=8;
|
|
|
|
base->records = (ha_rows) mi_sizekorr(ptr); ptr +=8;
|
|
|
|
base->reloc = (ha_rows) mi_sizekorr(ptr); ptr +=8;
|
|
|
|
base->mean_row_length = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
base->reclength = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
base->pack_reclength = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
base->min_pack_length = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
base->max_pack_length = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
base->min_block_length = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
base->fields = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
base->pack_fields = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
|
|
|
|
base->rec_reflength = *ptr++;
|
|
|
|
base->key_reflength = *ptr++;
|
|
|
|
base->keys= *ptr++;
|
|
|
|
base->auto_key= *ptr++;
|
|
|
|
base->pack_bits = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
base->blobs = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
base->max_key_block_length= mi_uint2korr(ptr); ptr +=2;
|
|
|
|
base->max_key_length = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
base->extra_alloc_bytes = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
base->extra_alloc_procent = *ptr++;
|
|
|
|
|
2010-07-23 17:15:07 -03:00
|
|
|
ptr+=13;
|
2000-07-31 21:29:14 +02:00
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
mi_keydef
|
|
|
|
---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
|
|
|
|
{
|
|
|
|
uchar buff[MI_KEYDEF_SIZE];
|
|
|
|
uchar *ptr=buff;
|
|
|
|
|
|
|
|
*ptr++ = (uchar) keydef->keysegs;
|
2002-05-22 18:51:21 +03:00
|
|
|
*ptr++ = keydef->key_alg; /* Rtree or Btree */
|
2000-07-31 21:29:14 +02:00
|
|
|
mi_int2store(ptr,keydef->flag); ptr +=2;
|
|
|
|
mi_int2store(ptr,keydef->block_length); ptr +=2;
|
|
|
|
mi_int2store(ptr,keydef->keylength); ptr +=2;
|
|
|
|
mi_int2store(ptr,keydef->minlength); ptr +=2;
|
|
|
|
mi_int2store(ptr,keydef->maxlength); ptr +=2;
|
2009-12-04 18:26:15 -07:00
|
|
|
return mysql_file_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2007-08-13 16:11:25 +03:00
|
|
|
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
keydef->keysegs = (uint) *ptr++;
|
2002-05-22 18:51:21 +03:00
|
|
|
keydef->key_alg = *ptr++; /* Rtree or Btree */
|
2002-02-20 14:11:21 +04:00
|
|
|
|
2000-07-31 21:29:14 +02:00
|
|
|
keydef->flag = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
keydef->block_length = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
keydef->keylength = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
keydef->minlength = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
keydef->maxlength = mi_uint2korr(ptr); ptr +=2;
|
2006-05-03 15:59:17 +03:00
|
|
|
keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
|
2000-07-31 21:29:14 +02:00
|
|
|
keydef->underflow_block_length=keydef->block_length/3;
|
|
|
|
keydef->version = 0; /* Not saved */
|
2005-11-06 13:13:06 +01:00
|
|
|
keydef->parser = &ft_default_parser;
|
2009-01-26 10:35:15 +04:00
|
|
|
keydef->ftkey_nr = 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
** mi_keyseg
|
|
|
|
***************************************************************************/
|
|
|
|
|
2002-04-25 15:10:29 +05:00
|
|
|
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
2002-04-25 15:10:29 +05:00
|
|
|
uchar buff[HA_KEYSEG_SIZE];
|
2000-07-31 21:29:14 +02:00
|
|
|
uchar *ptr=buff;
|
2004-12-31 00:44:00 +02:00
|
|
|
ulong pos;
|
2000-07-31 21:29:14 +02:00
|
|
|
|
2004-12-31 00:44:00 +02:00
|
|
|
*ptr++= keyseg->type;
|
2009-10-15 15:17:32 +05:00
|
|
|
*ptr++= keyseg->language & 0xFF; /* Collation ID, low byte */
|
2004-12-31 00:44:00 +02:00
|
|
|
*ptr++= keyseg->null_bit;
|
|
|
|
*ptr++= keyseg->bit_start;
|
2009-10-15 15:17:32 +05:00
|
|
|
*ptr++= keyseg->language >> 8; /* Collation ID, high byte */
|
2004-12-17 18:06:05 +04:00
|
|
|
*ptr++= keyseg->bit_length;
|
2000-07-31 21:29:14 +02:00
|
|
|
mi_int2store(ptr,keyseg->flag); ptr+=2;
|
|
|
|
mi_int2store(ptr,keyseg->length); ptr+=2;
|
|
|
|
mi_int4store(ptr,keyseg->start); ptr+=4;
|
2004-12-31 00:44:00 +02:00
|
|
|
pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
|
|
|
|
mi_int4store(ptr, pos);
|
2004-12-17 18:06:05 +04:00
|
|
|
ptr+=4;
|
|
|
|
|
2009-12-04 18:26:15 -07:00
|
|
|
return mysql_file_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-13 16:11:25 +03:00
|
|
|
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
keyseg->type = *ptr++;
|
|
|
|
keyseg->language = *ptr++;
|
|
|
|
keyseg->null_bit = *ptr++;
|
|
|
|
keyseg->bit_start = *ptr++;
|
2009-10-15 15:17:32 +05:00
|
|
|
keyseg->language += ((uint16) (*ptr++)) << 8;
|
2004-12-17 18:06:05 +04:00
|
|
|
keyseg->bit_length = *ptr++;
|
2000-07-31 21:29:14 +02:00
|
|
|
keyseg->flag = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
keyseg->length = mi_uint2korr(ptr); ptr +=2;
|
|
|
|
keyseg->start = mi_uint4korr(ptr); ptr +=4;
|
|
|
|
keyseg->null_pos = mi_uint4korr(ptr); ptr +=4;
|
2009-10-15 15:17:32 +05:00
|
|
|
keyseg->bit_end= 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
keyseg->charset=0; /* Will be filled in later */
|
2004-12-17 18:06:05 +04:00
|
|
|
if (keyseg->null_bit)
|
2009-04-29 14:00:34 +02:00
|
|
|
/* We adjust bit_pos if null_bit is last in the byte */
|
|
|
|
keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == (1 << 7)));
|
2004-12-17 18:06:05 +04:00
|
|
|
else
|
|
|
|
{
|
2005-03-18 16:12:25 -08:00
|
|
|
keyseg->bit_pos= (uint16)keyseg->null_pos;
|
2004-12-17 18:06:05 +04:00
|
|
|
keyseg->null_pos= 0;
|
|
|
|
}
|
2000-07-31 21:29:14 +02:00
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
mi_uniquedef
|
|
|
|
---------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
|
|
|
|
{
|
|
|
|
uchar buff[MI_UNIQUEDEF_SIZE];
|
|
|
|
uchar *ptr=buff;
|
|
|
|
|
|
|
|
mi_int2store(ptr,def->keysegs); ptr+=2;
|
|
|
|
*ptr++= (uchar) def->key;
|
|
|
|
*ptr++ = (uchar) def->null_are_equal;
|
|
|
|
|
2009-12-04 18:26:15 -07:00
|
|
|
return mysql_file_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2007-08-13 16:11:25 +03:00
|
|
|
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
def->keysegs = mi_uint2korr(ptr);
|
|
|
|
def->key = ptr[2];
|
|
|
|
def->null_are_equal=ptr[3];
|
|
|
|
return ptr+4; /* 1 extra byte */
|
|
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
** MI_COLUMNDEF
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
|
|
|
|
{
|
|
|
|
uchar buff[MI_COLUMNDEF_SIZE];
|
|
|
|
uchar *ptr=buff;
|
|
|
|
|
|
|
|
mi_int2store(ptr,recinfo->type); ptr +=2;
|
|
|
|
mi_int2store(ptr,recinfo->length); ptr +=2;
|
|
|
|
*ptr++ = recinfo->null_bit;
|
|
|
|
mi_int2store(ptr,recinfo->null_pos); ptr+= 2;
|
2009-12-04 18:26:15 -07:00
|
|
|
return mysql_file_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
|
2000-07-31 21:29:14 +02:00
|
|
|
}
|
|
|
|
|
2007-08-13 16:11:25 +03:00
|
|
|
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
|
2000-07-31 21:29:14 +02:00
|
|
|
{
|
|
|
|
recinfo->type= mi_sint2korr(ptr); ptr +=2;
|
|
|
|
recinfo->length=mi_uint2korr(ptr); ptr +=2;
|
|
|
|
recinfo->null_bit= (uint8) *ptr++;
|
|
|
|
recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
|
|
|
|
return ptr;
|
|
|
|
}
|
2000-10-17 00:47:15 +03:00
|
|
|
|
|
|
|
/**************************************************************************
|
2010-07-23 17:15:07 -03:00
|
|
|
Open data file.
|
2003-10-02 20:22:29 +02:00
|
|
|
We can't use dup() here as the data file descriptors need to have different
|
2001-08-21 13:44:01 +03:00
|
|
|
active seek-positions.
|
|
|
|
|
|
|
|
The argument file_to_dup is here for the future if there would on some OS
|
|
|
|
exist a dup()-like call that would give us two different file descriptors.
|
|
|
|
*************************************************************************/
|
2000-10-17 00:47:15 +03:00
|
|
|
|
2008-08-22 17:31:53 +05:00
|
|
|
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *org_name,
|
WL#3817: Simplify string / memory area types and make things more consistent (first part)
The following type conversions was done:
- Changed byte to uchar
- Changed gptr to uchar*
- Change my_string to char *
- Change my_size_t to size_t
- Change size_s to size_t
Removed declaration of byte, gptr, my_string, my_size_t and size_s.
Following function parameter changes was done:
- All string functions in mysys/strings was changed to use size_t
instead of uint for string lengths.
- All read()/write() functions changed to use size_t (including vio).
- All protocoll functions changed to use size_t instead of uint
- Functions that used a pointer to a string length was changed to use size_t*
- Changed malloc(), free() and related functions from using gptr to use void *
as this requires fewer casts in the code and is more in line with how the
standard functions work.
- Added extra length argument to dirname_part() to return the length of the
created string.
- Changed (at least) following functions to take uchar* as argument:
- db_dump()
- my_net_write()
- net_write_command()
- net_store_data()
- DBUG_DUMP()
- decimal2bin() & bin2decimal()
- Changed my_compress() and my_uncompress() to use size_t. Changed one
argument to my_uncompress() from a pointer to a value as we only return
one value (makes function easier to use).
- Changed type of 'pack_data' argument to packfrm() to avoid casts.
- Changed in readfrm() and writefrom(), ha_discover and handler::discover()
the type for argument 'frmdata' to uchar** to avoid casts.
- Changed most Field functions to use uchar* instead of char* (reduced a lot of
casts).
- Changed field->val_xxx(xxx, new_ptr) to take const pointers.
Other changes:
- Removed a lot of not needed casts
- Added a few new cast required by other changes
- Added some cast to my_multi_malloc() arguments for safety (as string lengths
needs to be uint, not size_t).
- Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done
explicitely as this conflict was often hided by casting the function to
hash_get_key).
- Changed some buffers to memory regions to uchar* to avoid casts.
- Changed some string lengths from uint to size_t.
- Changed field->ptr to be uchar* instead of char*. This allowed us to
get rid of a lot of casts.
- Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar
- Include zlib.h in some files as we needed declaration of crc32()
- Changed MY_FILE_ERROR to be (size_t) -1.
- Changed many variables to hold the result of my_read() / my_write() to be
size_t. This was needed to properly detect errors (which are
returned as (size_t) -1).
- Removed some very old VMS code
- Changed packfrm()/unpackfrm() to not be depending on uint size
(portability fix)
- Removed windows specific code to restore cursor position as this
causes slowdown on windows and we should not mix read() and pread()
calls anyway as this is not thread safe. Updated function comment to
reflect this. Changed function that depended on original behavior of
my_pwrite() to itself restore the cursor position (one such case).
- Added some missing checking of return value of malloc().
- Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow.
- Changed type of table_def::m_size from my_size_t to ulong to reflect that
m_size is the number of elements in the array, not a string/memory
length.
- Moved THD::max_row_length() to table.cc (as it's not depending on THD).
Inlined max_row_length_blob() into this function.
- More function comments
- Fixed some compiler warnings when compiled without partitions.
- Removed setting of LEX_STRING() arguments in declaration (portability fix).
- Some trivial indentation/variable name changes.
- Some trivial code simplifications:
- Replaced some calls to alloc_root + memcpy to use
strmake_root()/strdup_root().
- Changed some calls from memdup() to strmake() (Safety fix)
- Simpler loops in client-simple.c
2007-05-10 12:59:39 +03:00
|
|
|
File file_to_dup __attribute__((unused)))
|
2000-10-17 00:47:15 +03:00
|
|
|
{
|
2008-08-22 17:31:53 +05:00
|
|
|
char *data_name= share->data_file_name;
|
|
|
|
char real_data_name[FN_REFLEN];
|
|
|
|
|
|
|
|
if (org_name)
|
|
|
|
{
|
|
|
|
fn_format(real_data_name,org_name,"",MI_NAME_DEXT,4);
|
|
|
|
if (my_is_symlink(real_data_name))
|
|
|
|
{
|
|
|
|
if (my_realpath(real_data_name, real_data_name, MYF(0)) ||
|
|
|
|
(*myisam_test_invalid_symlink)(real_data_name))
|
|
|
|
{
|
|
|
|
my_errno= HA_WRONG_CREATE_OPTION;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
data_name= real_data_name;
|
|
|
|
}
|
|
|
|
}
|
2010-07-23 17:15:07 -03:00
|
|
|
info->dfile= mysql_file_open(mi_key_file_dfile,
|
|
|
|
data_name, share->mode | O_SHARE, MYF(MY_WME));
|
2001-08-19 14:43:51 +03:00
|
|
|
return info->dfile >= 0 ? 0 : 1;
|
2000-10-17 00:47:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int mi_open_keyfile(MYISAM_SHARE *share)
|
|
|
|
{
|
2009-12-04 18:26:15 -07:00
|
|
|
if ((share->kfile= mysql_file_open(mi_key_file_kfile,
|
|
|
|
share->unique_file_name,
|
|
|
|
share->mode | O_SHARE,
|
|
|
|
MYF(MY_WME))) < 0)
|
2000-10-17 00:47:15 +03:00
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
}
|
2004-05-06 15:53:01 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Disable all indexes.
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
mi_disable_indexes()
|
|
|
|
info A pointer to the MyISAM storage engine MI_INFO struct.
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Disable all indexes.
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
0 ok
|
|
|
|
*/
|
|
|
|
|
|
|
|
int mi_disable_indexes(MI_INFO *info)
|
|
|
|
{
|
|
|
|
MYISAM_SHARE *share= info->s;
|
|
|
|
|
2005-07-19 14:13:56 +02:00
|
|
|
mi_clear_all_keys_active(share->state.key_map);
|
2004-05-06 15:53:01 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Enable all indexes
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
mi_enable_indexes()
|
|
|
|
info A pointer to the MyISAM storage engine MI_INFO struct.
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Enable all indexes. The indexes might have been disabled
|
|
|
|
by mi_disable_index() before.
|
|
|
|
The function works only if both data and indexes are empty,
|
|
|
|
otherwise a repair is required.
|
|
|
|
To be sure, call handler::delete_all_rows() before.
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
0 ok
|
|
|
|
HA_ERR_CRASHED data or index is non-empty.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int mi_enable_indexes(MI_INFO *info)
|
|
|
|
{
|
|
|
|
int error= 0;
|
|
|
|
MYISAM_SHARE *share= info->s;
|
|
|
|
|
|
|
|
if (share->state.state.data_file_length ||
|
|
|
|
(share->state.state.key_file_length != share->base.keystart))
|
2004-12-23 20:11:38 +01:00
|
|
|
{
|
2004-12-31 03:47:56 +02:00
|
|
|
mi_print_error(info->s, HA_ERR_CRASHED);
|
2004-05-06 15:53:01 +02:00
|
|
|
error= HA_ERR_CRASHED;
|
2004-12-23 20:11:38 +01:00
|
|
|
}
|
2004-05-06 15:53:01 +02:00
|
|
|
else
|
2005-07-19 14:13:56 +02:00
|
|
|
mi_set_all_keys_active(share->state.key_map, share->base.keys);
|
2004-05-06 15:53:01 +02:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Test if indexes are disabled.
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
mi_indexes_are_disabled()
|
|
|
|
info A pointer to the MyISAM storage engine MI_INFO struct.
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Test if indexes are disabled.
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
0 indexes are not disabled
|
|
|
|
1 all indexes are disabled
|
2006-11-28 18:27:32 +01:00
|
|
|
2 non-unique indexes are disabled
|
2004-05-06 15:53:01 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
int mi_indexes_are_disabled(MI_INFO *info)
|
|
|
|
{
|
|
|
|
MYISAM_SHARE *share= info->s;
|
|
|
|
|
2006-11-28 18:27:32 +01:00
|
|
|
/*
|
|
|
|
No keys or all are enabled. keys is the number of keys. Left shifted
|
|
|
|
gives us only one bit set. When decreased by one, gives us all all bits
|
|
|
|
up to this one set and it gets unset.
|
|
|
|
*/
|
|
|
|
if (!share->base.keys ||
|
2006-11-30 18:36:15 +01:00
|
|
|
(mi_is_all_keys_active(share->state.key_map, share->base.keys)))
|
2006-11-28 18:27:32 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* All are disabled */
|
2006-11-30 18:36:15 +01:00
|
|
|
if (mi_is_any_key_active(share->state.key_map))
|
2006-11-28 18:27:32 +01:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
We have keys. Some enabled, some disabled.
|
|
|
|
Don't check for any non-unique disabled but return directly 2
|
|
|
|
*/
|
|
|
|
return 2;
|
2004-05-06 15:53:01 +02:00
|
|
|
}
|
|
|
|
|