Below is the list of changes that have just been committed into a local
5.1 repository of svoj. When svoj does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-03-13 19:05:35+04:00, svoj@april.(none) +5 -0
Merge mysql.com:/home/svoj/devel/mysql/BUG26881/mysql-5.0-engines
into mysql.com:/home/svoj/devel/mysql/BUG26881/mysql-5.1-engines
MERGE: 1.1810.2373.154
mysql-test/r/merge.result@stripped, 2007-03-13 19:05:29+04:00, svoj@april.(none) +0 -0
Auto merged
MERGE: 1.43.1.15
mysql-test/t/merge.test@stripped, 2007-03-13 19:05:29+04:00, svoj@april.(none) +0 -0
Auto merged
MERGE: 1.37.1.11
sql/sql_parse.cc@stripped, 2007-03-13 19:05:29+04:00, svoj@april.(none) +0 -0
Auto merged
MERGE: 1.426.1.184
storage/myisam/ha_myisam.cc@stripped, 2007-03-13 19:05:30+04:00, svoj@april.(none) +0 -0
Auto merged
MERGE: 1.147.14.2
storage/myisam/ha_myisam.cc@stripped, 2007-03-13 19:05:29+04:00, svoj@april.(none) +0 -0
Merge rename: sql/ha_myisam.cc -> storage/myisam/ha_myisam.cc
storage/myisam/mi_create.c@stripped, 2007-03-13 19:05:30+04:00, svoj@april.(none) +0 -0
Auto merged
MERGE: 1.45.18.2
storage/myisam/mi_create.c@stripped, 2007-03-13 19:05:29+04:00, svoj@april.(none) +0 -0
Merge rename: myisam/mi_create.c -> storage/myisam/mi_create.c
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: svoj
# Host: april.(none)
# Root: /home/svoj/devel/mysql/BUG26881/mysql-5.1-engines/RESYNC
--- 1.45.18.1/myisam/mi_create.c 2007-03-13 19:05:42 +04:00
+++ 1.67/storage/myisam/mi_create.c 2007-03-13 19:05:42 +04:00
@@ -27,9 +27,9 @@
#endif
#include <m_ctype.h>
- /*
- ** Old options is used when recreating database, from isamchk
- */
+/*
+ Old options is used when recreating database, from myisamchk
+*/
int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
uint columns, MI_COLUMNDEF *recinfo,
@@ -44,6 +44,7 @@ int mi_create(const char *name,uint keys
key_length,info_length,key_segs,options,min_key_length_skip,
base_pos,long_varchar_count,varchar_length,
max_key_block_length,unique_key_parts,fulltext_keys,offset;
+ uint aligned_key_start, block_length;
ulong reclength, real_reclength,min_pack_length;
char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr;
ulong pack_reclength;
@@ -188,6 +189,8 @@ int mi_create(const char *name,uint keys
}
if (flags & HA_CREATE_DELAY_KEY_WRITE)
options|= HA_OPTION_DELAY_KEY_WRITE;
+ if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
+ options|= HA_OPTION_RELIES_ON_SQL_LAYER;
packed=(packed+7)/8;
if (pack_reclength != INT_MAX32)
@@ -431,8 +434,16 @@ int mi_create(const char *name,uint keys
key_segs)
share.state.rec_per_key_part[key_segs-1]=1L;
length+=key_length;
+ /* Get block length for key, if defined by user */
+ block_length= (keydef->block_length ?
+ my_round_up_to_next_power(keydef->block_length) :
+ myisam_block_size);
+ block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+ block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
- pointer,MI_MAX_KEYPTR_SIZE);
+ pointer,MI_MAX_KEYPTR_SIZE,
+ block_length);
if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH ||
length >= MI_MAX_KEY_BUFF)
{
@@ -498,7 +509,7 @@ int mi_create(const char *name,uint keys
mi_int2store(share.state.header.base_pos,base_pos);
share.state.header.language= (ci->language ?
ci->language : default_charset_info->number);
- share.state.header.max_block_size=max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
+ share.state.header.max_block_size_index= max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH;
share.state.dellink = HA_OFFSET_ERROR;
share.state.process= (ulong) getpid();
@@ -525,8 +536,12 @@ int mi_create(const char *name,uint keys
mi_int2store(share.state.header.unique_key_parts,unique_key_parts);
mi_set_all_keys_active(share.state.key_map, keys);
- share.base.keystart = share.state.state.key_file_length=
- MY_ALIGN(info_length, myisam_block_size);
+ aligned_key_start= my_round_up_to_next_power(max_key_block_length ?
+ max_key_block_length :
+ myisam_block_size);
+
+ share.base.keystart= share.state.state.key_file_length=
+ MY_ALIGN(info_length, aligned_key_start);
share.base.max_key_block_length=max_key_block_length;
share.base.max_key_length=ALIGN_SIZE(max_key_length+4);
share.base.records=ci->max_rows;
@@ -560,6 +575,8 @@ int mi_create(const char *name,uint keys
if (ci->index_file_name)
{
+ char *iext= strrchr(ci->index_file_name, '.');
+ int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
if (options & HA_OPTION_TMP_TABLE)
{
char *path;
@@ -567,13 +584,17 @@ int mi_create(const char *name,uint keys
if ((path= strrchr(ci->index_file_name, FN_LIBCHAR)))
*path= '\0';
fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT,
- MY_REPLACE_DIR | MY_UNPACK_FILENAME);
+ MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
}
else
- fn_format(filename, ci->index_file_name, "",
- MI_NAME_IEXT, MY_UNPACK_FILENAME);
- fn_format(linkname, name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME);
- linkname_ptr= linkname;
+ {
+ fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT,
+ MY_UNPACK_FILENAME | (have_iext ? MY_REPLACE_EXT :
+ MY_APPEND_EXT));
+ }
+ fn_format(linkname, name, "", MI_NAME_IEXT,
+ MY_UNPACK_FILENAME|MY_APPEND_EXT);
+ linkname_ptr=linkname;
/*
Don't create the table if the link or file exists to ensure that one
doesn't accidently destroy another table.
@@ -582,8 +603,10 @@ int mi_create(const char *name,uint keys
}
else
{
- fn_format(filename,name,"",MI_NAME_IEXT,(4+ (flags & HA_DONT_TOUCH_DATA) ?
- 32 : 0));
+ fn_format(filename, name, "", MI_NAME_IEXT,
+ (MY_UNPACK_FILENAME |
+ (flags & HA_DONT_TOUCH_DATA) ? MY_RETURN_REAL_PATH : 0) |
+ MY_APPEND_EXT);
linkname_ptr=0;
/* Replace the current file */
create_flag=MY_DELETE_OLD;
@@ -614,7 +637,8 @@ int mi_create(const char *name,uint keys
#ifdef USE_RAID
if (share.base.raid_type)
{
- (void) fn_format(filename,name,"",MI_NAME_DEXT,2+4);
+ (void) fn_format(filename, name, "", MI_NAME_DEXT,
+ MY_UNPACK_FILENAME | MY_APPEND_EXT);
if ((dfile=my_raid_create(filename, 0, create_mode,
share.base.raid_type,
share.base.raid_chunks,
@@ -627,6 +651,9 @@ int mi_create(const char *name,uint keys
{
if (ci->data_file_name)
{
+ char *dext= strrchr(ci->data_file_name, '.');
+ int have_dext= dext && !strcmp(dext, MI_NAME_DEXT);
+
if (options & HA_OPTION_TMP_TABLE)
{
char *path;
@@ -634,18 +661,24 @@ int mi_create(const char *name,uint keys
if ((path= strrchr(ci->data_file_name, FN_LIBCHAR)))
*path= '\0';
fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT,
- MY_REPLACE_DIR | MY_UNPACK_FILENAME);
+ MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT);
}
else
- fn_format(filename, ci->data_file_name, "",
- MI_NAME_DEXT, MY_UNPACK_FILENAME);
- fn_format(linkname, name, "", MI_NAME_DEXT, MY_UNPACK_FILENAME);
- linkname_ptr= linkname;
- create_flag= 0;
+ {
+ fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT,
+ MY_UNPACK_FILENAME |
+ (have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT));
+ }
+
+ fn_format(linkname, name, "",MI_NAME_DEXT,
+ MY_UNPACK_FILENAME | MY_APPEND_EXT);
+ linkname_ptr=linkname;
+ create_flag=0;
}
else
{
- fn_format(filename,name,"",MI_NAME_DEXT,4);
+ fn_format(filename,name,"", MI_NAME_DEXT,
+ MY_UNPACK_FILENAME | MY_APPEND_EXT);
linkname_ptr=0;
create_flag=MY_DELETE_OLD;
}
@@ -799,13 +832,15 @@ err:
case 2:
if (! (flags & HA_DONT_TOUCH_DATA))
- my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,2+4),
+ my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_DEXT,
+ MY_UNPACK_FILENAME | MY_APPEND_EXT),
MYF(0));
/* fall through */
case 1:
VOID(my_close(file,MYF(0)));
if (! (flags & HA_DONT_TOUCH_DATA))
- my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,2+4),
+ my_delete_with_symlink(fn_format(filename,name,"",MI_NAME_IEXT,
+ MY_UNPACK_FILENAME | MY_APPEND_EXT),
MYF(0));
}
my_free((char*) rec_per_key_part, MYF(0));
--- 1.147.14.1/sql/ha_myisam.cc 2007-03-13 19:05:42 +04:00
+++ 1.211/storage/myisam/ha_myisam.cc 2007-03-13 19:05:42 +04:00
@@ -18,17 +18,15 @@
#pragma implementation // gcc: Class implementation
#endif
+#define MYSQL_SERVER 1
#include "mysql_priv.h"
+#include <mysql/plugin.h>
#include <m_ctype.h>
#include <myisampack.h>
#include "ha_myisam.h"
#include <stdarg.h>
-#ifndef MASTER
-#include "../srclib/myisam/myisamdef.h"
-#else
-#include "../myisam/myisamdef.h"
-#include "../myisam/rt_index.h"
-#endif
+#include "myisamdef.h"
+#include "rt_index.h"
ulong myisam_recover_options= HA_RECOVER_NONE;
@@ -49,35 +47,12 @@ TYPELIB myisam_stats_method_typelib= {
** MyISAM tables
*****************************************************************************/
-/* MyISAM handlerton */
-
-handlerton myisam_hton= {
- "MyISAM",
- SHOW_OPTION_YES,
- "Default engine as of MySQL 3.23 with great performance",
- DB_TYPE_MYISAM,
- NULL,
- 0, /* slot */
- 0, /* savepoint size. */
- NULL, /* close_connection */
- NULL, /* savepoint */
- NULL, /* rollback to savepoint */
- NULL, /* release savepoint */
- NULL, /* commit */
- NULL, /* rollback */
- NULL, /* prepare */
- NULL, /* recover */
- NULL, /* commit_by_xid */
- NULL, /* rollback_by_xid */
- NULL, /* create_cursor_read_view */
- NULL, /* set_cursor_read_view */
- NULL, /* close_cursor_read_view */
- /*
- MyISAM doesn't support transactions and doesn't have
- transaction-dependent context: cursors can survive a commit.
- */
- HTON_CAN_RECREATE
-};
+static handler *myisam_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
+{
+ return new (mem_root) ha_myisam(hton, table);
+}
// collect errors printed by mi_check routines
@@ -146,6 +121,7 @@ int table2myisam(TABLE *table_arg, MI_KE
{
uint i, j, recpos, minpos, fieldpos, temp_length, length;
enum ha_base_keytype type= HA_KEYTYPE_BINARY;
+ byte *record;
KEY *pos;
MI_KEYDEF *keydef;
MI_COLUMNDEF *recinfo, *recinfo_pos;
@@ -169,6 +145,7 @@ int table2myisam(TABLE *table_arg, MI_KE
keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ?
(pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) :
pos->algorithm;
+ keydef[i].block_length= pos->block_size;
keydef[i].seg= keyseg;
keydef[i].keysegs= pos->key_parts;
for (j= 0; j < pos->key_parts; j++)
@@ -217,15 +194,15 @@ int table2myisam(TABLE *table_arg, MI_KE
keydef[i].seg[j].null_bit= 0;
keydef[i].seg[j].null_pos= 0;
}
- if (field->type() == FIELD_TYPE_BLOB ||
- field->type() == FIELD_TYPE_GEOMETRY)
+ if (field->type() == MYSQL_TYPE_BLOB ||
+ field->type() == MYSQL_TYPE_GEOMETRY)
{
keydef[i].seg[j].flag|= HA_BLOB_PART;
/* save number of bytes used to pack length */
keydef[i].seg[j].bit_start= (uint) (field->pack_length() -
share->blob_ptr_size);
}
- else if (field->type() == FIELD_TYPE_BIT)
+ else if (field->type() == MYSQL_TYPE_BIT)
{
keydef[i].seg[j].bit_length= ((Field_bit *) field)->bit_len;
keydef[i].seg[j].bit_start= ((Field_bit *) field)->bit_ofs;
@@ -237,6 +214,7 @@ int table2myisam(TABLE *table_arg, MI_KE
}
if (table_arg->found_next_number_field)
keydef[share->next_number_index].flag|= HA_AUTO_KEY;
+ record= table_arg->record[0];
recpos= 0;
recinfo_pos= recinfo;
while (recpos < (uint) share->reclength)
@@ -247,7 +225,7 @@ int table2myisam(TABLE *table_arg, MI_KE
for (field= table_arg->field; *field; field++)
{
- if ((fieldpos= (*field)->offset()) >= recpos &&
+ if ((fieldpos= (*field)->offset(record)) >= recpos &&
fieldpos <= minpos)
{
/* skip null fields */
@@ -493,13 +471,14 @@ void mi_check_print_warning(MI_CHECK *pa
}
-ha_myisam::ha_myisam(TABLE *table_arg)
- :handler(&myisam_hton, table_arg), file(0),
+ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
+ :handler(hton, table_arg), file(0),
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
- HA_DUPP_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
- HA_FILE_BASED | HA_CAN_GEOMETRY | HA_READ_RND_SAME |
- HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS),
- can_enable_indexes(1)
+ HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY |
+ HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS |
+ HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS |
+ HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT),
+ can_enable_indexes(1)
{}
handler *ha_myisam::clone(MEM_ROOT *mem_root)
@@ -618,15 +597,67 @@ err:
}
#endif /* HAVE_REPLICATION */
+
+bool ha_myisam::check_if_locking_is_allowed(uint sql_command,
+ ulong type, TABLE *table,
+ uint count,
+ bool called_by_privileged_thread)
+{
+ /*
+ To be able to open and lock for reading system tables like 'mysql.proc',
+ when we already have some tables opened and locked, and avoid deadlocks
+ we have to disallow write-locking of these tables with any other tables.
+ */
+ if (table->s->system_table &&
+ table->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE &&
+ count != 1)
+ {
+ my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0), table->s->db.str,
+ table->s->table_name.str);
+ return FALSE;
+ }
+
+ /*
+ Deny locking of the log tables, which is incompatible with
+ concurrent insert. Unless called from a logger THD (general_log_thd
+ or slow_log_thd) or by a privileged thread.
+ */
+ if (!called_by_privileged_thread)
+ return check_if_log_table_locking_is_allowed(sql_command, type, table);
+
+ return TRUE;
+}
+
/* Name is here without an extension */
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{
- if (!(file=mi_open(name, mode, test_if_locked)))
+ uint i;
+
+ /*
+ If the user wants to have memory mapped data files, add an
+ open_flag. Do not memory map temporary tables because they are
+ expected to be inserted and thus extended a lot. Memory mapping is
+ efficient for files that keep their size, but very inefficient for
+ growing files. Using an open_flag instead of calling mi_extra(...
+ HA_EXTRA_MMAP ...) after mi_open() has the advantage that the
+ mapping is not repeated for every open, but just done on the initial
+ open, when the MyISAM share is created. Everytime the server
+ requires to open a new instance of a table it calls this method. We
+ will always supply HA_OPEN_MMAP for a permanent table. However, the
+ MyISAM storage engine will ignore this flag if this is a secondary
+ open of a table that is in use by other threads already (if the
+ MyISAM share exists already).
+ */
+ if (!(test_if_locked & HA_OPEN_TMP_TABLE) && opt_myisam_use_mmap)
+ test_if_locked|= HA_OPEN_MMAP;
+
+ if (!(file=mi_open(name, mode, test_if_locked | HA_OPEN_FROM_SQL_LAYER)))
return (my_errno ? my_errno : -1);
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
+
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
VOID(mi_extra(file, HA_EXTRA_WAIT_LOCK, 0));
@@ -634,6 +665,15 @@ int ha_myisam::open(const char *name, in
int_table_flags|=HA_REC_NOT_IN_SEQ;
if (file->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
int_table_flags|=HA_HAS_CHECKSUM;
+
+ for (i= 0; i < table->s->keys; i++)
+ {
+ struct st_plugin_int *parser= table->key_info[i].parser;
+ if (table->key_info[i].flags & HA_USES_PARSER)
+ file->s->keyinfo[i].parser=
+ (struct st_mysql_ftparser *)parser->plugin->info;
+ table->key_info[i].block_size= file->s->keyinfo[i].block_length;
+ }
return (0);
}
@@ -677,7 +717,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_
myisamchk_init(¶m);
param.thd = thd;
param.op_name = "check";
- param.db_name= table->s->db;
+ param.db_name= table->s->db.str;
param.table_name= table->alias;
param.testflag = check_opt->flags | T_CHECK | T_SILENT;
param.stats_method= (enum_mi_stats_method)thd->variables.myisam_stats_method;
@@ -767,7 +807,7 @@ int ha_myisam::analyze(THD *thd, HA_CHEC
myisamchk_init(¶m);
param.thd = thd;
param.op_name= "analyze";
- param.db_name= table->s->db;
+ param.db_name= table->s->db.str;
param.table_name= table->alias;
param.testflag= (T_FAST | T_CHECK | T_SILENT | T_STATISTICS |
T_DONT_CHECK_CHECKSUM);
@@ -795,17 +835,20 @@ int ha_myisam::restore(THD* thd, HA_CHEC
HA_CHECK_OPT tmp_check_opt;
char *backup_dir= thd->lex->backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- const char *table_name= table->s->table_name;
+ char table_name[FN_REFLEN];
int error;
const char* errmsg;
DBUG_ENTER("restore");
+ VOID(tablename_to_filename(table->s->table_name.str, table_name,
+ sizeof(table_name)));
+
if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
MI_NAME_DEXT))
DBUG_RETURN(HA_ADMIN_INVALID);
- if (my_copy(src_path, fn_format(dst_path, table->s->path, "",
- MI_NAME_DEXT, 4), MYF(MY_WME)))
+ strxmov(dst_path, table->s->normalized_path.str, MI_NAME_DEXT, NullS);
+ if (my_copy(src_path, dst_path, MYF(MY_WME)))
{
error= HA_ADMIN_FAILED;
errmsg= "Failed in my_copy (Error %d)";
@@ -822,8 +865,8 @@ int ha_myisam::restore(THD* thd, HA_CHEC
myisamchk_init(¶m);
param.thd= thd;
param.op_name= "restore";
- param.db_name= table->s->db;
- param.table_name= table->s->table_name;
+ param.db_name= table->s->db.str;
+ param.table_name= table->s->table_name.str;
param.testflag= 0;
mi_check_print_error(¶m, errmsg, my_errno);
DBUG_RETURN(error);
@@ -835,11 +878,14 @@ int ha_myisam::backup(THD* thd, HA_CHECK
{
char *backup_dir= thd->lex->backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- const char *table_name= table->s->table_name;
+ char table_name[FN_REFLEN];
int error;
const char *errmsg;
DBUG_ENTER("ha_myisam::backup");
+ VOID(tablename_to_filename(table->s->table_name.str, table_name,
+ sizeof(table_name)));
+
if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir,
reg_ext))
{
@@ -848,9 +894,8 @@ int ha_myisam::backup(THD* thd, HA_CHECK
goto err;
}
- if (my_copy(fn_format(src_path, table->s->path, "", reg_ext,
- MY_UNPACK_FILENAME),
- dst_path,
+ strxmov(src_path, table->s->normalized_path.str, reg_ext, NullS);
+ if (my_copy(src_path, dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE)))
{
error = HA_ADMIN_FAILED;
@@ -859,17 +904,16 @@ int ha_myisam::backup(THD* thd, HA_CHECK
}
/* Change extension */
- if (!fn_format(dst_path, dst_path, "", MI_NAME_DEXT,
- MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH))
+ if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir,
+ MI_NAME_DEXT))
{
errmsg = "Failed in fn_format() for .MYD file (errno: %d)";
error = HA_ADMIN_INVALID;
goto err;
}
- if (my_copy(fn_format(src_path, table->s->path, "", MI_NAME_DEXT,
- MY_UNPACK_FILENAME),
- dst_path,
+ strxmov(src_path, table->s->normalized_path.str, MI_NAME_DEXT, NullS);
+ if (my_copy(src_path, dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE)))
{
errmsg = "Failed copying .MYD file (errno: %d)";
@@ -884,8 +928,8 @@ int ha_myisam::backup(THD* thd, HA_CHECK
myisamchk_init(¶m);
param.thd= thd;
param.op_name= "backup";
- param.db_name= table->s->db;
- param.table_name= table->s->table_name;
+ param.db_name= table->s->db.str;
+ param.table_name= table->s->table_name.str;
param.testflag = 0;
mi_check_print_error(¶m,errmsg, my_errno);
DBUG_RETURN(error);
@@ -917,7 +961,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK
{
param.testflag&= ~T_RETRY_WITHOUT_QUICK;
sql_print_information("Retrying repair of: '%s' without quick",
- table->s->path);
+ table->s->path.str);
continue;
}
param.testflag&= ~T_QUICK;
@@ -925,7 +969,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK
{
param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;
sql_print_information("Retrying repair of: '%s' with keycache",
- table->s->path);
+ table->s->path.str);
continue;
}
break;
@@ -937,7 +981,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK
sql_print_information("Found %s of %s rows when repairing '%s'",
llstr(file->state->records, llbuff),
llstr(start_records, llbuff2),
- table->s->path);
+ table->s->path.str);
}
return error;
}
@@ -976,7 +1020,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK
ha_rows rows= file->state->records;
DBUG_ENTER("ha_myisam::repair");
- param.db_name= table->s->db;
+ param.db_name= table->s->db.str;
param.table_name= table->alias;
param.tmpfile_createflag = O_RDWR | O_TRUNC;
param.using_global_keycache = 1;
@@ -1147,8 +1191,8 @@ int ha_myisam::assign_to_keycache(THD* t
myisamchk_init(¶m);
param.thd= thd;
param.op_name= "assign_to_keycache";
- param.db_name= table->s->db;
- param.table_name= table->s->table_name;
+ param.db_name= table->s->db.str;
+ param.table_name= table->s->table_name.str;
param.testflag= 0;
mi_check_print_error(¶m, errmsg);
}
@@ -1215,8 +1259,8 @@ int ha_myisam::preload_keys(THD* thd, HA
myisamchk_init(¶m);
param.thd= thd;
param.op_name= "preload_keys";
- param.db_name= table->s->db;
- param.table_name= table->s->table_name;
+ param.db_name= table->s->db.str;
+ param.table_name= table->s->table_name.str;
param.testflag= 0;
mi_check_print_error(¶m, errmsg);
DBUG_RETURN(error);
@@ -1465,18 +1509,18 @@ bool ha_myisam::check_and_repair(THD *th
// Don't use quick if deleted rows
if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
check_opt.flags|=T_QUICK;
- sql_print_warning("Checking table: '%s'",table->s->path);
+ sql_print_warning("Checking table: '%s'",table->s->path.str);
old_query= thd->query;
old_query_length= thd->query_length;
pthread_mutex_lock(&LOCK_thread_count);
- thd->query= (char*) table->s->table_name;
- thd->query_length= (uint32) strlen(table->s->table_name);
+ thd->query= table->s->table_name.str;
+ thd->query_length= table->s->table_name.length;
pthread_mutex_unlock(&LOCK_thread_count);
if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
{
- sql_print_warning("Recovering table: '%s'",table->s->path);
+ sql_print_warning("Recovering table: '%s'",table->s->path.str);
check_opt.flags=
((myisam_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
(marked_crashed ? 0 : T_QUICK) |
@@ -1535,12 +1579,13 @@ int ha_myisam::index_read_idx(byte * buf
int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len)
{
+ DBUG_ENTER("ha_myisam::index_read_last");
DBUG_ASSERT(inited==INDEX);
statistic_increment(table->in_use->status_var.ha_read_key_count,
&LOCK_status);
int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
table->status=error ? STATUS_NOT_FOUND: 0;
- return error;
+ DBUG_RETURN(error);
}
int ha_myisam::index_next(byte * buf)
@@ -1600,7 +1645,7 @@ int ha_myisam::rnd_init(bool scan)
{
if (scan)
return mi_scan_init(file);
- return mi_extra(file, HA_EXTRA_RESET, 0);
+ return mi_reset(file); // Free buffers
}
int ha_myisam::rnd_next(byte *buf)
@@ -1640,24 +1685,27 @@ int ha_myisam::info(uint flag)
(void) mi_status(file,&misam_info,flag);
if (flag & HA_STATUS_VARIABLE)
{
- records= misam_info.records;
- deleted= misam_info.deleted;
- data_file_length= misam_info.data_file_length;
- index_file_length= misam_info.index_file_length;
- delete_length= misam_info.delete_length;
- check_time= misam_info.check_time;
- mean_rec_length= misam_info.mean_reclength;
+ stats.records= misam_info.records;
+ stats.deleted= misam_info.deleted;
+ stats.data_file_length= misam_info.data_file_length;
+ stats.index_file_length= misam_info.index_file_length;
+ stats.delete_length= misam_info.delete_length;
+ stats.check_time= misam_info.check_time;
+ stats.mean_rec_length= misam_info.mean_reclength;
}
if (flag & HA_STATUS_CONST)
{
TABLE_SHARE *share= table->s;
- max_data_file_length= misam_info.max_data_file_length;
- max_index_file_length= misam_info.max_index_file_length;
- create_time= misam_info.create_time;
- sortkey= misam_info.sortkey;
+ stats.max_data_file_length= misam_info.max_data_file_length;
+ stats.max_index_file_length= misam_info.max_index_file_length;
+ stats.create_time= misam_info.create_time;
ref_length= misam_info.reflength;
share->db_options_in_use= misam_info.options;
- block_size= myisam_block_size;
+ stats.block_size= myisam_block_size; /* record block size */
+
+ /* Update share */
+ if (share->tmp_table == NO_TMP_TABLE)
+ pthread_mutex_lock(&share->mutex);
share->keys_in_use.set_prefix(share->keys);
share->keys_in_use.intersect_extended(misam_info.key_map);
share->keys_for_keyread.intersect(share->keys_in_use);
@@ -1666,31 +1714,32 @@ int ha_myisam::info(uint flag)
memcpy((char*) table->key_info[0].rec_per_key,
(char*) misam_info.rec_per_key,
sizeof(table->key_info[0].rec_per_key)*share->key_parts);
- raid_type= misam_info.raid_type;
- raid_chunks= misam_info.raid_chunks;
- raid_chunksize= misam_info.raid_chunksize;
+ if (share->tmp_table == NO_TMP_TABLE)
+ pthread_mutex_unlock(&share->mutex);
/*
Set data_file_name and index_file_name to point at the symlink value
if table is symlinked (Ie; Real name is not same as generated name)
*/
- data_file_name=index_file_name=0;
- fn_format(name_buff, file->filename, "", MI_NAME_DEXT, 2);
+ data_file_name= index_file_name= 0;
+ fn_format(name_buff, file->filename, "", MI_NAME_DEXT,
+ MY_APPEND_EXT | MY_UNPACK_FILENAME);
if (strcmp(name_buff, misam_info.data_file_name))
- data_file_name= misam_info.data_file_name;
- strmov(fn_ext(name_buff),MI_NAME_IEXT);
+ data_file_name=misam_info.data_file_name;
+ fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
+ MY_APPEND_EXT | MY_UNPACK_FILENAME);
if (strcmp(name_buff, misam_info.index_file_name))
- index_file_name= misam_info.index_file_name;
+ index_file_name=misam_info.index_file_name;
}
if (flag & HA_STATUS_ERRKEY)
{
errkey = misam_info.errkey;
- my_store_ptr(dupp_ref, ref_length, misam_info.dupp_key_pos);
+ my_store_ptr(dup_ref, ref_length, misam_info.dupp_key_pos);
}
if (flag & HA_STATUS_TIME)
- update_time = misam_info.update_time;
+ stats.update_time = misam_info.update_time;
if (flag & HA_STATUS_AUTO)
- auto_increment_value= misam_info.auto_increment;
+ stats.auto_increment_value= misam_info.auto_increment;
return 0;
}
@@ -1703,6 +1752,10 @@ int ha_myisam::extra(enum ha_extra_funct
return mi_extra(file, operation, 0);
}
+int ha_myisam::reset(void)
+{
+ return mi_reset(file);
+}
/* To be used with WRITE_CACHE and EXTRA_CACHE */
@@ -1746,13 +1799,7 @@ void ha_myisam::update_create_info(HA_CR
ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST);
if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
{
- create_info->auto_increment_value=auto_increment_value;
- }
- if (!(create_info->used_fields & HA_CREATE_USED_RAID))
- {
- create_info->raid_type= raid_type;
- create_info->raid_chunks= raid_chunks;
- create_info->raid_chunksize= raid_chunksize;
+ create_info->auto_increment_value= stats.auto_increment_value;
}
create_info->data_file_name=data_file_name;
create_info->index_file_name=index_file_name;
@@ -1763,14 +1810,22 @@ int ha_myisam::create(const char *name,
HA_CREATE_INFO *ha_create_info)
{
int error;
- uint create_flags= 0, records;
+ uint create_flags= 0, records, i;
char buff[FN_REFLEN];
MI_KEYDEF *keydef;
MI_COLUMNDEF *recinfo;
MI_CREATE_INFO create_info;
- TABLE_SHARE *share= table->s;
+ TABLE_SHARE *share= table_arg->s;
uint options= share->db_options_in_use;
DBUG_ENTER("ha_myisam::create");
+ for (i= 0; i < share->keys; i++)
+ {
+ if (table_arg->key_info[i].flags & HA_USES_PARSER)
+ {
+ create_flags|= HA_CREATE_RELIES_ON_SQL_LAYER;
+ break;
+ }
+ }
if ((error= table2myisam(table_arg, &keydef, &recinfo, &records)))
DBUG_RETURN(error); /* purecov: inspected */
bzero((char*) &create_info, sizeof(create_info));
@@ -1782,13 +1837,6 @@ int ha_myisam::create(const char *name,
(ulonglong) 0);
create_info.data_file_length= ((ulonglong) share->max_rows *
share->avg_row_length);
- create_info.raid_type= ha_create_info->raid_type;
- create_info.raid_chunks= (ha_create_info->raid_chunks ?
- ha_create_info->raid_chunks :
- RAID_DEFAULT_CHUNKS);
- create_info.raid_chunksize= (ha_create_info->raid_chunksize ?
- ha_create_info->raid_chunksize :
- RAID_DEFAULT_CHUNKSIZE);
create_info.data_file_name= ha_create_info->data_file_name;
create_info.index_file_name= ha_create_info->index_file_name;
@@ -1803,7 +1851,7 @@ int ha_myisam::create(const char *name,
/* TODO: Check that the following fn_format is really needed */
error= mi_create(fn_format(buff, name, "", "",
- MY_UNPACK_FILENAME|MY_REPLACE_EXT),
+ MY_UNPACK_FILENAME|MY_APPEND_EXT),
share->keys, keydef,
records, recinfo,
0, (MI_UNIQUEDEF*) 0,
@@ -1819,7 +1867,10 @@ int ha_myisam::rename_table(const char *
}
-ulonglong ha_myisam::get_auto_increment()
+void ha_myisam::get_auto_increment(ulonglong offset, ulonglong increment,
+ ulonglong nb_desired_values,
+ ulonglong *first_value,
+ ulonglong *nb_reserved_values)
{
ulonglong nr;
int error;
@@ -1828,7 +1879,10 @@ ulonglong ha_myisam::get_auto_increment(
if (!table->s->next_number_key_offset)
{ // Autoincrement at key-start
ha_myisam::info(HA_STATUS_AUTO);
- return auto_increment_value;
+ *first_value= stats.auto_increment_value;
+ /* MyISAM has only table-level lock, so reserves to +inf */
+ *nb_reserved_values= ULONGLONG_MAX;
+ return;
}
/* it's safe to call the following if bulk_insert isn't on */
@@ -1849,7 +1903,14 @@ ulonglong ha_myisam::get_auto_increment(
val_int_offset(table->s->rec_buff_length)+1);
}
extra(HA_EXTRA_NO_KEYREAD);
- return nr;
+ *first_value= nr;
+ /*
+ MySQL needs to call us for next row: assume we are inserting ("a",null)
+ here, we return 3, and next this statement will want to insert ("b",null):
+ there is no reason why ("b",3+1) would be the good row to insert: maybe it
+ already exists, maybe 3+1 is too large...
+ */
+ *nb_reserved_values= 1;
}
@@ -1905,4 +1966,64 @@ uint ha_myisam::checksum() const
{
return (uint)file->state->checksum;
}
+
+
+bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes)
+{
+ uint options= table->s->db_options_in_use;
+
+ if (info->auto_increment_value != stats.auto_increment_value ||
+ info->data_file_name != data_file_name ||
+ info->index_file_name != index_file_name ||
+ table_changes == IS_EQUAL_NO ||
+ table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet
+ return COMPATIBLE_DATA_NO;
+
+ if ((options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM |
+ HA_OPTION_DELAY_KEY_WRITE)) !=
+ (info->table_options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM |
+ HA_OPTION_DELAY_KEY_WRITE)))
+ return COMPATIBLE_DATA_NO;
+ return COMPATIBLE_DATA_YES;
+}
+
+extern int mi_panic(enum ha_panic_function flag);
+int myisam_panic(handlerton *hton, ha_panic_function flag)
+{
+ return mi_panic(flag);
+}
+
+static int myisam_init(void *p)
+{
+ handlerton *myisam_hton;
+
+ myisam_hton= (handlerton *)p;
+ myisam_hton->state= SHOW_OPTION_YES;
+ myisam_hton->db_type= DB_TYPE_MYISAM;
+ myisam_hton->create= myisam_create_handler;
+ myisam_hton->panic= myisam_panic;
+ myisam_hton->flags= HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES;
+ return 0;
+}
+
+struct st_mysql_storage_engine myisam_storage_engine=
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+
+mysql_declare_plugin(myisam)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisam_storage_engine,
+ "MyISAM",
+ "MySQL AB",
+ "Default engine as of MySQL 3.23 with great performance",
+ PLUGIN_LICENSE_GPL,
+ myisam_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+}
+mysql_declare_plugin_end;
--- 1.61/mysql-test/r/merge.result 2007-03-13 19:05:42 +04:00
+++ 1.62/mysql-test/r/merge.result 2007-03-13 19:05:42 +04:00
@@ -811,6 +811,19 @@ CREATE TABLE t2(c1 INT) ENGINE=MERGE UNI
INSERT DELAYED INTO t2 VALUES(1);
ERROR HY000: Table storage engine for 't2' doesn't have this option
DROP TABLE t1, t2;
+CREATE TABLE t1(c1 VARCHAR(1));
+CREATE TABLE m1 LIKE t1;
+ALTER TABLE m1 ENGINE=MERGE UNION=(t1);
+SELECT * FROM m1;
+c1
+DROP TABLE t1, m1;
+CREATE TABLE t1(c1 VARCHAR(4), c2 TINYINT, c3 TINYINT, c4 TINYINT,
+c5 TINYINT, c6 TINYINT, c7 TINYINT, c8 TINYINT, c9 TINYINT);
+CREATE TABLE m1 LIKE t1;
+ALTER TABLE m1 ENGINE=MERGE UNION=(t1);
+SELECT * FROM m1;
+c1 c2 c3 c4 c5 c6 c7 c8 c9
+DROP TABLE t1, m1;
create table t1 (b bit(1));
create table t2 (b bit(1));
create table tm (b bit(1)) engine = merge union = (t1,t2);
--- 1.50/mysql-test/t/merge.test 2007-03-13 19:05:42 +04:00
+++ 1.51/mysql-test/t/merge.test 2007-03-13 19:05:42 +04:00
@@ -443,6 +443,23 @@ CREATE TABLE t2(c1 INT) ENGINE=MERGE UNI
INSERT DELAYED INTO t2 VALUES(1);
DROP TABLE t1, t2;
+#
+# BUG#26881 - Large MERGE tables report incorrect specification when no
+# differences in tables
+#
+CREATE TABLE t1(c1 VARCHAR(1));
+CREATE TABLE m1 LIKE t1;
+ALTER TABLE m1 ENGINE=MERGE UNION=(t1);
+SELECT * FROM m1;
+DROP TABLE t1, m1;
+
+CREATE TABLE t1(c1 VARCHAR(4), c2 TINYINT, c3 TINYINT, c4 TINYINT,
+ c5 TINYINT, c6 TINYINT, c7 TINYINT, c8 TINYINT, c9 TINYINT);
+CREATE TABLE m1 LIKE t1;
+ALTER TABLE m1 ENGINE=MERGE UNION=(t1);
+SELECT * FROM m1;
+DROP TABLE t1, m1;
+
# End of 4.1 tests
#
| Thread |
|---|
| • bk commit into 5.1 tree (svoj:1.2479) | Sergey Vojtovich | 13 Mar |