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-01-31 18:57:54+04:00, svoj@stripped +4 -0
Merge mysql.com:/home/svoj/devel/mysql/WL3567/mysql-5.0-engines
into mysql.com:/home/svoj/devel/mysql/WL3567/mysql-5.1-engines
MERGE: 1.1810.2371.66
mysql-test/r/merge.result@stripped, 2007-01-31 18:34:57+04:00, svoj@stripped +0 -0
Auto merged
MERGE: 1.43.1.13
mysql-test/t/merge.test@stripped, 2007-01-31 18:34:57+04:00, svoj@stripped +0 -0
Auto merged
MERGE: 1.37.1.9
storage/myisam/ha_myisam.cc@stripped, 2007-01-31 18:57:53+04:00, svoj@stripped +18
-12
Manually merged.
MERGE: 1.147.10.3
storage/myisam/ha_myisam.cc@stripped, 2007-01-31 18:34:57+04:00, svoj@stripped
+0 -0
Merge rename: sql/ha_myisam.cc -> storage/myisam/ha_myisam.cc
storage/myisammrg/ha_myisammrg.cc@stripped, 2007-01-31 18:57:53+04:00, svoj@stripped
+1 -2
Manually merged.
MERGE: 1.59.12.3
storage/myisammrg/ha_myisammrg.cc@stripped, 2007-01-31 18:34:57+04:00,
svoj@stripped +0 -0
Merge rename: sql/ha_myisammrg.cc -> storage/myisammrg/ha_myisammrg.cc
# 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: june.mysql.com
# Root: /home/svoj/devel/mysql/WL3567/mysql-5.1-engines/RESYNC
--- 1.147.10.2/sql/ha_myisam.cc 2007-01-31 18:32:51 +04:00
+++ 1.207/storage/myisam/ha_myisam.cc 2007-01-31 18:57:53 +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 */
@@ -458,13 +436,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)
@@ -583,15 +562,51 @@ 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 (!(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));
+
+ if (!(test_if_locked & HA_OPEN_TMP_TABLE) && opt_myisam_use_mmap)
+ VOID(mi_extra(file, HA_EXTRA_MMAP, 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));
@@ -599,6 +614,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);
}
@@ -642,7 +666,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;
@@ -732,7 +756,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);
@@ -760,17 +784,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)";
@@ -787,8 +814,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);
@@ -800,11 +827,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))
{
@@ -813,9 +843,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;
@@ -824,17 +853,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)";
@@ -849,8 +877,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);
@@ -882,7 +910,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;
@@ -890,7 +918,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;
@@ -902,7 +930,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;
}
@@ -941,7 +969,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;
@@ -1112,8 +1140,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);
}
@@ -1180,8 +1208,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);
@@ -1430,18 +1458,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) |
@@ -1500,12 +1528,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)
@@ -1565,7 +1594,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)
@@ -1605,24 +1634,27 @@ int ha_myisam::info(uint flag)
(void) mi_status(file,&info,flag);
if (flag & HA_STATUS_VARIABLE)
{
- records = info.records;
- deleted = info.deleted;
- data_file_length=info.data_file_length;
- index_file_length=info.index_file_length;
- delete_length = info.delete_length;
- check_time = info.check_time;
- mean_rec_length=info.mean_reclength;
+ stats.records = info.records;
+ stats.deleted = info.deleted;
+ stats.data_file_length=info.data_file_length;
+ stats.index_file_length=info.index_file_length;
+ stats.delete_length = info.delete_length;
+ stats.check_time = info.check_time;
+ stats. mean_rec_length=info.mean_reclength;
}
if (flag & HA_STATUS_CONST)
{
TABLE_SHARE *share= table->s;
- max_data_file_length= info.max_data_file_length;
- max_index_file_length= info.max_index_file_length;
- create_time= info.create_time;
- sortkey= info.sortkey;
+ stats.max_data_file_length= info.max_data_file_length;
+ stats.max_index_file_length= info.max_index_file_length;
+ stats.create_time= info.create_time;
ref_length= info.reflength;
share->db_options_in_use= 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(info.key_map);
share->keys_for_keyread.intersect(share->keys_in_use);
@@ -1631,31 +1663,32 @@ int ha_myisam::info(uint flag)
memcpy((char*) table->key_info[0].rec_per_key,
(char*) info.rec_per_key,
sizeof(table->key_info[0].rec_per_key)*share->key_parts);
- raid_type= info.raid_type;
- raid_chunks= info.raid_chunks;
- raid_chunksize= 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, info.data_file_name))
data_file_name=info.data_file_name;
- strmov(fn_ext(name_buff),MI_NAME_IEXT);
+ fn_format(name_buff, file->filename, "", MI_NAME_IEXT,
+ MY_APPEND_EXT | MY_UNPACK_FILENAME);
if (strcmp(name_buff, info.index_file_name))
index_file_name=info.index_file_name;
}
if (flag & HA_STATUS_ERRKEY)
{
errkey = info.errkey;
- my_store_ptr(dupp_ref, ref_length, info.dupp_key_pos);
+ my_store_ptr(dup_ref, ref_length, info.dupp_key_pos);
}
if (flag & HA_STATUS_TIME)
- update_time = info.update_time;
+ stats.update_time = info.update_time;
if (flag & HA_STATUS_AUTO)
- auto_increment_value= info.auto_increment;
+ stats.auto_increment_value= info.auto_increment;
return 0;
}
@@ -1668,6 +1701,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 */
@@ -1711,13 +1748,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;
@@ -1728,14 +1759,22 @@ int ha_myisam::create(const char *name,
HA_CREATE_INFO *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));
@@ -1747,11 +1786,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= info->raid_type;
- create_info.raid_chunks= (info->raid_chunks ? info->raid_chunks :
- RAID_DEFAULT_CHUNKS);
- create_info.raid_chunksize= (info->raid_chunksize ? info->raid_chunksize :
- RAID_DEFAULT_CHUNKSIZE);
create_info.data_file_name= info->data_file_name;
create_info.index_file_name= info->index_file_name;
@@ -1766,7 +1800,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,
@@ -1782,7 +1816,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;
@@ -1791,7 +1828,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 */
@@ -1812,7 +1852,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;
}
@@ -1868,4 +1915,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.59.12.2/sql/ha_myisammrg.cc 2007-01-31 18:32:51 +04:00
+++ 1.112/storage/myisammrg/ha_myisammrg.cc 2007-01-31 18:57:53 +04:00
@@ -18,48 +18,31 @@
#pragma implementation // gcc: Class implementation
#endif
+#define MYSQL_SERVER 1
#include "mysql_priv.h"
+#include <mysql/plugin.h>
#include <m_ctype.h>
#include "ha_myisammrg.h"
-#ifndef MASTER
-#include "../srclib/myisammrg/myrg_def.h"
-#else
-#include "../myisammrg/myrg_def.h"
-#endif
+#include "myrg_def.h"
+
/*****************************************************************************
** MyISAM MERGE tables
*****************************************************************************/
-/* MyISAM MERGE handlerton */
+static handler *myisammrg_create_handler(TABLE_SHARE *table,
+ MEM_ROOT *mem_root);
-handlerton myisammrg_hton= {
- "MRG_MYISAM",
- SHOW_OPTION_YES,
- "Collection of identical MyISAM tables",
- DB_TYPE_MRG_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 */
- HTON_CAN_RECREATE
-};
+static handler *myisammrg_create_handler(handlerton *hton,
+ TABLE_SHARE *table,
+ MEM_ROOT *mem_root)
+{
+ return new (mem_root) ha_myisammrg(hton, table);
+}
-ha_myisammrg::ha_myisammrg(TABLE *table_arg)
- :handler(&myisammrg_hton, table_arg), file(0)
+ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg)
+ :handler(hton, table_arg), file(0)
{}
static const char *ha_myisammrg_exts[] = {
@@ -102,13 +85,14 @@ int ha_myisammrg::open(const char *name,
char name_buff[FN_REFLEN];
DBUG_PRINT("info", ("ha_myisammrg::open"));
- if (!(file=myrg_open(fn_format(name_buff,name,"","",2 | 4), mode,
- test_if_locked)))
+ if (!(file=myrg_open(fn_format(name_buff,name,"","",
+ MY_UNPACK_FILENAME|MY_APPEND_EXT),
+ mode, test_if_locked)))
{
DBUG_PRINT("info", ("ha_myisammrg::open exit %d", my_errno));
return (my_errno ? my_errno : -1);
}
- DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc..."))
+ DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc..."));
myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref);
if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED ||
test_if_locked == HA_OPEN_ABORT_IF_LOCKED))
@@ -117,10 +101,10 @@ int ha_myisammrg::open(const char *name,
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
myrg_extra(file,HA_EXTRA_WAIT_LOCK,0);
- if (table->s->reclength != mean_rec_length && mean_rec_length)
+ if (table->s->reclength != stats.mean_rec_length &&
stats.mean_rec_length)
{
DBUG_PRINT("error",("reclength: %lu mean_rec_length: %lu",
- table->s->reclength, mean_rec_length));
+ table->s->reclength, stats.mean_rec_length));
error= HA_ERR_WRONG_MRG_TABLE_DEF;
goto err;
}
@@ -274,11 +258,13 @@ int ha_myisammrg::index_next_same(byte *
return error;
}
+
int ha_myisammrg::rnd_init(bool scan)
{
- return myrg_extra(file,HA_EXTRA_RESET,0);
+ return myrg_reset(file);
}
+
int ha_myisammrg::rnd_next(byte *buf)
{
statistic_increment(table->in_use->status_var.ha_read_rnd_next_count,
@@ -288,6 +274,7 @@ int ha_myisammrg::rnd_next(byte *buf)
return error;
}
+
int ha_myisammrg::rnd_pos(byte * buf, byte *pos)
{
statistic_increment(table->in_use->status_var.ha_read_rnd_count,
@@ -319,19 +306,18 @@ int ha_myisammrg::info(uint flag)
The following fails if one has not compiled MySQL with -DBIG_TABLES
and one has more than 2^32 rows in the merge tables.
*/
- records = (ha_rows) info.records;
- deleted = (ha_rows) info.deleted;
+ stats.records = (ha_rows) info.records;
+ stats.deleted = (ha_rows) info.deleted;
#if !defined(BIG_TABLES) || SIZEOF_OFF_T == 4
if ((info.records >= (ulonglong) 1 << 32) ||
(info.deleted >= (ulonglong) 1 << 32))
table->s->crashed= 1;
#endif
- data_file_length=info.data_file_length;
+ stats.data_file_length=info.data_file_length;
errkey = info.errkey;
table->s->keys_in_use.set_prefix(table->s->keys);
table->s->db_options_in_use= info.options;
- table->s->is_view= 1;
- mean_rec_length= info.reclength;
+ stats.mean_rec_length= info.reclength;
/*
The handler::block_size is used all over the code in index scan cost
@@ -349,11 +335,11 @@ int ha_myisammrg::info(uint flag)
TODO: In 5.2 index scan cost calculation will be factored out into a
virtual function in class handler and we'll be able to remove this hack.
*/
- block_size= 0;
+ stats.block_size= 0;
if (file->tables)
- block_size= myisam_block_size / file->tables;
+ stats.block_size= myisam_block_size / file->tables;
- update_time=0;
+ stats.update_time= 0;
#if SIZEOF_OFF_T > 4
ref_length=6; // Should be big enough
#else
@@ -393,6 +379,10 @@ int ha_myisammrg::extra(enum ha_extra_fu
return myrg_extra(file,operation,0);
}
+int ha_myisammrg::reset(void)
+{
+ return myrg_reset(file);
+}
/* To be used with WRITE_CACHE, EXTRA_CACHE and BULK_INSERT_BEGIN */
@@ -518,9 +508,9 @@ int ha_myisammrg::create(const char *nam
for (pos= table_names; tables; tables= tables->next_local)
{
const char *table_name;
- TABLE **tbl= 0;
+ TABLE *tbl= 0;
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
- tbl= find_temporary_table(thd, tables->db, tables->table_name);
+ tbl= find_temporary_table(thd, tables);
if (!tbl)
{
/*
@@ -534,8 +524,8 @@ int ha_myisammrg::create(const char *nam
This means that it might not be possible to move the DATADIR of
an embedded server without changing the paths in the .MRG file.
*/
- uint length= my_snprintf(buff, FN_REFLEN, "%s/%s/%s", mysql_data_home,
- tables->db, tables->table_name);
+ uint length= build_table_filename(buff, sizeof(buff),
+ tables->db, tables->table_name, "", 0);
/*
If a MyISAM table is in the same directory as the MERGE table,
we use the table name without a path. This means that the
@@ -549,11 +539,13 @@ int ha_myisammrg::create(const char *nam
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
else
- table_name= (*tbl)->s->path;
+ table_name= tbl->s->path.str;
*pos++= table_name;
}
*pos=0;
- DBUG_RETURN(myrg_create(fn_format(buff,name,"","",2+4+16),
+ DBUG_RETURN(myrg_create(fn_format(buff,name,"","",
+ MY_RESOLVE_SYMLINKS|
+ MY_UNPACK_FILENAME|MY_APPEND_EXT),
table_names,
create_info->merge_insert_method,
(my_bool) 0));
@@ -565,6 +557,7 @@ void ha_myisammrg::append_create_info(St
const char *current_db;
uint db_length;
THD *thd= current_thd;
+ MYRG_TABLE *open_table, *first;
if (file->merge_insert_method != MERGE_INSERT_DISABLED)
{
@@ -572,10 +565,9 @@ void ha_myisammrg::append_create_info(St
packet->append(get_type(&merge_insert_method,file->merge_insert_method-1));
}
packet->append(STRING_WITH_LEN(" UNION=("));
- MYRG_TABLE *open_table,*first;
- current_db= table->s->db;
- db_length= (uint) strlen(current_db);
+ current_db= table->s->db.str;
+ db_length= table->s->db.length;
for (first=open_table=file->open_tables ;
open_table != file->end_table ;
@@ -597,3 +589,55 @@ void ha_myisammrg::append_create_info(St
}
packet->append(')');
}
+
+
+bool ha_myisammrg::check_if_incompatible_data(HA_CREATE_INFO *info,
+ uint table_changes)
+{
+ /*
+ For myisammrg, we should always re-generate the mapping file as this
+ is trivial to do
+ */
+ return COMPATIBLE_DATA_NO;
+}
+
+extern int myrg_panic(enum ha_panic_function flag);
+int myisammrg_panic(handlerton *hton, ha_panic_function flag)
+{
+ return myrg_panic(flag);
+}
+
+static int myisammrg_init(void *p)
+{
+ handlerton *myisammrg_hton;
+
+ myisammrg_hton= (handlerton *)p;
+
+ myisammrg_hton->state= SHOW_OPTION_YES;
+ myisammrg_hton->db_type= DB_TYPE_MRG_MYISAM;
+ myisammrg_hton->create= myisammrg_create_handler;
+ myisammrg_hton->panic= myisammrg_panic;
+ myisammrg_hton->flags= HTON_CAN_RECREATE|HTON_NO_PARTITION;
+
+ return 0;
+}
+
+struct st_mysql_storage_engine myisammrg_storage_engine=
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+
+mysql_declare_plugin(myisammrg)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &myisammrg_storage_engine,
+ "MRG_MYISAM",
+ "MySQL AB",
+ "Collection of identical MyISAM tables",
+ PLUGIN_LICENSE_GPL,
+ myisammrg_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100, /* 1.0 */
+ NULL, /* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+}
+mysql_declare_plugin_end;
--- 1.59/mysql-test/r/merge.result 2006-10-19 19:01:34 +05:00
+++ 1.60/mysql-test/r/merge.result 2007-01-31 18:34:57 +04:00
@@ -775,7 +775,7 @@ CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(2),(1);
CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1);
SELECT * FROM t2 WHERE a=2;
-ERROR HY000: Got error 124 from storage engine
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
DROP TABLE t1, t2;
CREATE TABLE t1(a INT) ENGINE=MEMORY;
CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1);
@@ -786,6 +786,26 @@ CREATE TABLE t2(a INT) ENGINE=MERGE UNIO
SELECT * FROM t2;
ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
DROP TABLE t2;
+CREATE TABLE t1(a INT, b TEXT);
+CREATE TABLE tm1(a TEXT, b INT) ENGINE=MERGE UNION=(t1);
+SELECT * FROM tm1;
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+DROP TABLE t1, tm1;
+CREATE TABLE t1(a SMALLINT, b SMALLINT);
+CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1);
+SELECT * FROM tm1;
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+DROP TABLE t1, tm1;
+CREATE TABLE t1(a SMALLINT, b SMALLINT, KEY(a, b));
+CREATE TABLE tm1(a SMALLINT, b SMALLINT, KEY(a)) ENGINE=MERGE UNION=(t1);
+SELECT * FROM tm1;
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+DROP TABLE t1, tm1;
+CREATE TABLE t1(a SMALLINT, b SMALLINT, KEY(b));
+CREATE TABLE tm1(a SMALLINT, b SMALLINT, KEY(a)) ENGINE=MERGE UNION=(t1);
+SELECT * FROM tm1;
+ERROR HY000: Unable to open underlying table which is differently defined or of
non-MyISAM type or doesn't exist
+DROP TABLE t1, tm1;
create table t1 (b bit(1));
create table t2 (b bit(1));
create table tm (b bit(1)) engine = merge union = (t1,t2);
--- 1.47/mysql-test/t/merge.test 2006-09-29 01:36:14 +05:00
+++ 1.48/mysql-test/t/merge.test 2007-01-31 18:34:57 +04:00
@@ -389,7 +389,7 @@ drop table t1, t2, t3;
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(2),(1);
CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1);
---error 1030
+--error 1168
SELECT * FROM t2 WHERE a=2;
DROP TABLE t1, t2;
@@ -406,6 +406,33 @@ CREATE TABLE t2(a INT) ENGINE=MERGE UNIO
--error 1168
SELECT * FROM t2;
DROP TABLE t2;
+
+#
+# Underlying table definition conformance tests.
+#
+CREATE TABLE t1(a INT, b TEXT);
+CREATE TABLE tm1(a TEXT, b INT) ENGINE=MERGE UNION=(t1);
+--error 1168
+SELECT * FROM tm1;
+DROP TABLE t1, tm1;
+
+CREATE TABLE t1(a SMALLINT, b SMALLINT);
+CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1);
+--error 1168
+SELECT * FROM tm1;
+DROP TABLE t1, tm1;
+
+CREATE TABLE t1(a SMALLINT, b SMALLINT, KEY(a, b));
+CREATE TABLE tm1(a SMALLINT, b SMALLINT, KEY(a)) ENGINE=MERGE UNION=(t1);
+--error 1168
+SELECT * FROM tm1;
+DROP TABLE t1, tm1;
+
+CREATE TABLE t1(a SMALLINT, b SMALLINT, KEY(b));
+CREATE TABLE tm1(a SMALLINT, b SMALLINT, KEY(a)) ENGINE=MERGE UNION=(t1);
+--error 1168
+SELECT * FROM tm1;
+DROP TABLE t1, tm1;
# End of 4.1 tests
| Thread |
|---|
| • bk commit into 5.1 tree (svoj:1.2406) | Sergey Vojtovich | 31 Jan |