Commit bb6be1e1 authored by acurtis@bk-internal.mysql.com's avatar acurtis@bk-internal.mysql.com

Merge bk-internal.mysql.com:/data0/bk/tmp-5.1

into  bk-internal.mysql.com:/data0/bk/mysql-5.1-engines
parents 6d40321b 4c52d3dd
...@@ -241,3 +241,11 @@ select * from t1 where match a against('ab c' in boolean mode); ...@@ -241,3 +241,11 @@ select * from t1 where match a against('ab c' in boolean mode);
a a
drop table t1; drop table t1;
set names latin1; set names latin1;
SET NAMES utf8;
CREATE TABLE t1(a VARCHAR(255), FULLTEXT(a)) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO t1 VALUES('„MySQL“');
SELECT a FROM t1 WHERE MATCH a AGAINST('“MySQL„' IN BOOLEAN MODE);
a
„MySQL“
DROP TABLE t1;
SET NAMES latin1;
...@@ -66,3 +66,11 @@ Select_priv ...@@ -66,3 +66,11 @@ Select_priv
N N
use test; use test;
use test; use test;
CREATE DATABASE mysqltest_1;
FLUSH TABLES WITH READ LOCK;
DROP DATABASE mysqltest_1;
DROP DATABASE mysqltest_1;
ERROR HY000: Can't execute the query because you have a conflicting read lock
UNLOCK TABLES;
DROP DATABASE mysqltest_1;
ERROR HY000: Can't drop database 'mysqltest_1'; database doesn't exist
...@@ -221,3 +221,13 @@ drop table t1; ...@@ -221,3 +221,13 @@ drop table t1;
set names latin1; set names latin1;
# End of 4.1 tests # End of 4.1 tests
#
# BUG#19580 - FULLTEXT search produces wrong results on UTF-8 columns
#
SET NAMES utf8;
CREATE TABLE t1(a VARCHAR(255), FULLTEXT(a)) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO t1 VALUES('„MySQL“');
SELECT a FROM t1 WHERE MATCH a AGAINST('“MySQL„' IN BOOLEAN MODE);
DROP TABLE t1;
SET NAMES latin1;
...@@ -158,3 +158,36 @@ use test; ...@@ -158,3 +158,36 @@ use test;
connection default; connection default;
# End of 5.0 tests # End of 5.0 tests
# Bug#19815 - CREATE/RENAME/DROP DATABASE can deadlock on a global read lock
#
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
#
connection con1;
CREATE DATABASE mysqltest_1;
FLUSH TABLES WITH READ LOCK;
#
# With bug in place: acquire LOCK_mysql_create_table and
# wait in wait_if_global_read_lock().
connection con2;
send DROP DATABASE mysqltest_1;
--sleep 1
#
# With bug in place: try to acquire LOCK_mysql_create_table...
# When fixed: Reject dropping db because of the read lock.
connection con1;
--error ER_CANT_UPDATE_WITH_READLOCK
DROP DATABASE mysqltest_1;
UNLOCK TABLES;
#
connection con2;
reap;
#
connection default;
disconnect con1;
disconnect con2;
# This must have been dropped by connection 2 already,
# which waited until the global read lock was released.
--error ER_DB_DROP_EXISTS
DROP DATABASE mysqltest_1;
...@@ -68,14 +68,14 @@ ulong total_ha_2pc= 0; ...@@ -68,14 +68,14 @@ ulong total_ha_2pc= 0;
/* size of savepoint storage area (see ha_init) */ /* size of savepoint storage area (see ha_init) */
ulong savepoint_alloc_size= 0; ulong savepoint_alloc_size= 0;
struct show_table_alias_st sys_table_aliases[]= static const LEX_STRING sys_table_aliases[]=
{ {
{"INNOBASE", DB_TYPE_INNODB}, {(char*)STRING_WITH_LEN("INNOBASE")}, {(char*)STRING_WITH_LEN("INNODB")},
{"NDB", DB_TYPE_NDBCLUSTER}, {(char*)STRING_WITH_LEN("NDB")}, {(char*)STRING_WITH_LEN("NDBCLUSTER")},
{"BDB", DB_TYPE_BERKELEY_DB}, {(char*)STRING_WITH_LEN("BDB")}, {(char*)STRING_WITH_LEN("BERKELEYDB")},
{"HEAP", DB_TYPE_HEAP}, {(char*)STRING_WITH_LEN("HEAP")}, {(char*)STRING_WITH_LEN("MEMORY")},
{"MERGE", DB_TYPE_MRG_MYISAM}, {(char*)STRING_WITH_LEN("MERGE")}, {(char*)STRING_WITH_LEN("MRG_MYISAM")},
{NullS, DB_TYPE_UNKNOWN} {NullS, 0}
}; };
const char *ha_row_type[] = { const char *ha_row_type[] = {
...@@ -91,15 +91,50 @@ TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"", ...@@ -91,15 +91,50 @@ TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
static TYPELIB known_extensions= {0,"known_exts", NULL, NULL}; static TYPELIB known_extensions= {0,"known_exts", NULL, NULL};
uint known_extensions_id= 0; uint known_extensions_id= 0;
handlerton *ha_resolve_by_name(THD *thd, LEX_STRING *name)
/*
Return the default storage engine handlerton for thread
SYNOPSIS
ha_default_handlerton(thd)
thd current thread
RETURN
pointer to handlerton
*/
handlerton *ha_default_handlerton(THD *thd)
{
return (thd->variables.table_type != NULL) ?
thd->variables.table_type :
(global_system_variables.table_type != NULL ?
global_system_variables.table_type : &myisam_hton);
}
/*
Return the storage engine handlerton for the supplied name
SYNOPSIS
ha_resolve_by_name(thd, name)
thd current thread
name name of storage engine
RETURN
pointer to handlerton
*/
handlerton *ha_resolve_by_name(THD *thd, const LEX_STRING *name)
{ {
show_table_alias_st *table_alias; const LEX_STRING *table_alias;
st_plugin_int *plugin; st_plugin_int *plugin;
if (thd && !my_strnncoll(&my_charset_latin1, redo:
/* my_strnncoll is a macro and gcc doesn't do early expansion of macro */
if (thd && !my_charset_latin1.coll->strnncoll(&my_charset_latin1,
(const uchar *)name->str, name->length, (const uchar *)name->str, name->length,
(const uchar *)"DEFAULT", 7)) (const uchar *)STRING_WITH_LEN("DEFAULT"), 0))
return ha_resolve_by_legacy_type(thd, DB_TYPE_DEFAULT); return ha_default_handlerton(thd);
if ((plugin= plugin_lock(name, MYSQL_STORAGE_ENGINE_PLUGIN))) if ((plugin= plugin_lock(name, MYSQL_STORAGE_ENGINE_PLUGIN)))
{ {
...@@ -112,13 +147,15 @@ handlerton *ha_resolve_by_name(THD *thd, LEX_STRING *name) ...@@ -112,13 +147,15 @@ handlerton *ha_resolve_by_name(THD *thd, LEX_STRING *name)
/* /*
We check for the historical aliases. We check for the historical aliases.
*/ */
for (table_alias= sys_table_aliases; table_alias->type; table_alias++) for (table_alias= sys_table_aliases; table_alias->str; table_alias+= 2)
{ {
if (!my_strnncoll(&my_charset_latin1, if (!my_strnncoll(&my_charset_latin1,
(const uchar *)name->str, name->length, (const uchar *)name->str, name->length,
(const uchar *)table_alias->alias, (const uchar *)table_alias->str, table_alias->length))
strlen(table_alias->alias))) {
return ha_resolve_by_legacy_type(thd, table_alias->type); name= table_alias + 1;
goto redo;
}
} }
return NULL; return NULL;
...@@ -130,20 +167,20 @@ const char *ha_get_storage_engine(enum legacy_db_type db_type) ...@@ -130,20 +167,20 @@ const char *ha_get_storage_engine(enum legacy_db_type db_type)
switch (db_type) { switch (db_type) {
case DB_TYPE_DEFAULT: case DB_TYPE_DEFAULT:
return "DEFAULT"; return "DEFAULT";
case DB_TYPE_UNKNOWN:
return "UNKNOWN";
default: default:
if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT && if (db_type > DB_TYPE_UNKNOWN && db_type < DB_TYPE_DEFAULT &&
installed_htons[db_type]) installed_htons[db_type])
return hton2plugin[installed_htons[db_type]->slot]->name.str; return hton2plugin[installed_htons[db_type]->slot]->name.str;
return "*NONE*"; /* fall through */
case DB_TYPE_UNKNOWN:
return "UNKNOWN";
} }
} }
static handler *create_default(TABLE_SHARE *table, MEM_ROOT *mem_root) static handler *create_default(TABLE_SHARE *table, MEM_ROOT *mem_root)
{ {
handlerton *hton=ha_resolve_by_legacy_type(current_thd, DB_TYPE_DEFAULT); handlerton *hton= ha_default_handlerton(current_thd);
return (hton && hton->create) ? hton->create(table, mem_root) : NULL; return (hton && hton->create) ? hton->create(table, mem_root) : NULL;
} }
...@@ -152,10 +189,7 @@ handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type) ...@@ -152,10 +189,7 @@ handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
{ {
switch (db_type) { switch (db_type) {
case DB_TYPE_DEFAULT: case DB_TYPE_DEFAULT:
return (thd->variables.table_type != NULL) ? return ha_default_handlerton(thd);
thd->variables.table_type :
(global_system_variables.table_type != NULL ?
global_system_variables.table_type : &myisam_hton);
case DB_TYPE_UNKNOWN: case DB_TYPE_UNKNOWN:
return NULL; return NULL;
default: default:
...@@ -196,7 +230,7 @@ handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type, ...@@ -196,7 +230,7 @@ handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
break; break;
} }
return ha_resolve_by_legacy_type(thd, DB_TYPE_DEFAULT); return ha_default_handlerton(thd);
} /* ha_checktype */ } /* ha_checktype */
......
...@@ -667,10 +667,6 @@ struct handlerton ...@@ -667,10 +667,6 @@ struct handlerton
struct handler_iterator *fill_this_in); struct handler_iterator *fill_this_in);
}; };
struct show_table_alias_st {
const char *alias;
enum legacy_db_type type;
};
/* Possible flags of a handlerton */ /* Possible flags of a handlerton */
#define HTON_NO_FLAGS 0 #define HTON_NO_FLAGS 0
...@@ -1545,7 +1541,8 @@ extern ulong total_ha, total_ha_2pc; ...@@ -1545,7 +1541,8 @@ extern ulong total_ha, total_ha_2pc;
#define ha_rollback(thd) (ha_rollback_trans((thd), TRUE)) #define ha_rollback(thd) (ha_rollback_trans((thd), TRUE))
/* lookups */ /* lookups */
handlerton *ha_resolve_by_name(THD *thd, LEX_STRING *name); handlerton *ha_default_handlerton(THD *thd);
handlerton *ha_resolve_by_name(THD *thd, const LEX_STRING *name);
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type); handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
const char *ha_get_storage_engine(enum legacy_db_type db_type); const char *ha_get_storage_engine(enum legacy_db_type db_type);
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc, handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
......
...@@ -4983,11 +4983,12 @@ Disable with --skip-bdb (will save memory).", ...@@ -4983,11 +4983,12 @@ Disable with --skip-bdb (will save memory).",
(gptr*) &default_collation_name, (gptr*) &default_collation_name, (gptr*) &default_collation_name, (gptr*) &default_collation_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"default-storage-engine", OPT_STORAGE_ENGINE, {"default-storage-engine", OPT_STORAGE_ENGINE,
"Set the default storage engine (table type) for tables.", 0, 0, "Set the default storage engine (table type) for tables.",
(gptr*)&default_storage_engine_str, (gptr*)&default_storage_engine_str,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"default-table-type", OPT_STORAGE_ENGINE, {"default-table-type", OPT_STORAGE_ENGINE,
"(deprecated) Use --default-storage-engine.", "(deprecated) Use --default-storage-engine.",
(gptr*)default_storage_engine_str, (gptr*)default_storage_engine_str, (gptr*)&default_storage_engine_str, (gptr*)&default_storage_engine_str,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.", {"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.",
(gptr*) &default_tz_name, (gptr*) &default_tz_name, (gptr*) &default_tz_name, (gptr*) &default_tz_name,
......
...@@ -538,16 +538,27 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, ...@@ -538,16 +538,27 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
my_error(ER_DB_CREATE_EXISTS, MYF(0), db); my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
/* do not create database if another thread is holding read lock */ /*
Do not create database if another thread is holding read lock.
Wait for global read lock before acquiring LOCK_mysql_create_db.
After wait_if_global_read_lock() we have protection against another
global read lock. If we would acquire LOCK_mysql_create_db first,
another thread could step in and get the global read lock before we
reach wait_if_global_read_lock(). If this thread tries the same as we
(admin a db), it would then go and wait on LOCK_mysql_create_db...
Furthermore wait_if_global_read_lock() checks if the current thread
has the global read lock and refuses the operation with
ER_CANT_UPDATE_WITH_READLOCK if applicable.
*/
if (wait_if_global_read_lock(thd, 0, 1)) if (wait_if_global_read_lock(thd, 0, 1))
{ {
error= -1; error= -1;
goto exit2; goto exit2;
} }
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
/* Check directory */ /* Check directory */
path_len= build_table_filename(path, sizeof(path), db, "", ""); path_len= build_table_filename(path, sizeof(path), db, "", "");
path[path_len-1]= 0; // Remove last '/' from path path[path_len-1]= 0; // Remove last '/' from path
...@@ -655,9 +666,9 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, ...@@ -655,9 +666,9 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
} }
exit: exit:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
exit2: exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -671,12 +682,23 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) ...@@ -671,12 +682,23 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
int error= 0; int error= 0;
DBUG_ENTER("mysql_alter_db"); DBUG_ENTER("mysql_alter_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); /*
Do not alter database if another thread is holding read lock.
/* do not alter database if another thread is holding read lock */ Wait for global read lock before acquiring LOCK_mysql_create_db.
After wait_if_global_read_lock() we have protection against another
global read lock. If we would acquire LOCK_mysql_create_db first,
another thread could step in and get the global read lock before we
reach wait_if_global_read_lock(). If this thread tries the same as we
(admin a db), it would then go and wait on LOCK_mysql_create_db...
Furthermore wait_if_global_read_lock() checks if the current thread
has the global read lock and refuses the operation with
ER_CANT_UPDATE_WITH_READLOCK if applicable.
*/
if ((error=wait_if_global_read_lock(thd,0,1))) if ((error=wait_if_global_read_lock(thd,0,1)))
goto exit2; goto exit2;
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
/* /*
Recreate db options file: /dbpath/.db.opt Recreate db options file: /dbpath/.db.opt
We pass MY_DB_OPT_FILE as "extension" to avoid We pass MY_DB_OPT_FILE as "extension" to avoid
...@@ -721,9 +743,9 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) ...@@ -721,9 +743,9 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
send_ok(thd, result); send_ok(thd, result);
exit: exit:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
exit2: exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -755,15 +777,26 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -755,15 +777,26 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
TABLE_LIST* dropped_tables= 0; TABLE_LIST* dropped_tables= 0;
DBUG_ENTER("mysql_rm_db"); DBUG_ENTER("mysql_rm_db");
VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); /*
Do not drop database if another thread is holding read lock.
/* do not drop database if another thread is holding read lock */ Wait for global read lock before acquiring LOCK_mysql_create_db.
After wait_if_global_read_lock() we have protection against another
global read lock. If we would acquire LOCK_mysql_create_db first,
another thread could step in and get the global read lock before we
reach wait_if_global_read_lock(). If this thread tries the same as we
(admin a db), it would then go and wait on LOCK_mysql_create_db...
Furthermore wait_if_global_read_lock() checks if the current thread
has the global read lock and refuses the operation with
ER_CANT_UPDATE_WITH_READLOCK if applicable.
*/
if (wait_if_global_read_lock(thd, 0, 1)) if (wait_if_global_read_lock(thd, 0, 1))
{ {
error= -1; error= -1;
goto exit2; goto exit2;
} }
VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
length= build_table_filename(path, sizeof(path), db, "", ""); length= build_table_filename(path, sizeof(path), db, "", "");
strmov(path+length, MY_DB_OPT_FILE); // Append db option file name strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
del_dbopt(path); // Remove dboption hash entry del_dbopt(path); // Remove dboption hash entry
...@@ -872,7 +905,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -872,7 +905,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
exit: exit:
(void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */ (void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */
error= Events::drop_schema_events(thd, db); error= Events::drop_schema_events(thd, db);
start_waiting_global_read_lock(thd);
/* /*
If this database was the client's selected database, we silently change the If this database was the client's selected database, we silently change the
client's selected database to nothing (to have an empty SELECT DATABASE() client's selected database to nothing (to have an empty SELECT DATABASE()
...@@ -901,9 +933,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -901,9 +933,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
thd->db= 0; thd->db= 0;
thd->db_length= 0; thd->db_length= 0;
} }
exit2:
VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
start_waiting_global_read_lock(thd);
exit2:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
......
...@@ -23,7 +23,7 @@ extern struct st_mysql_plugin *mysqld_builtins[]; ...@@ -23,7 +23,7 @@ extern struct st_mysql_plugin *mysqld_builtins[];
char *opt_plugin_dir_ptr; char *opt_plugin_dir_ptr;
char opt_plugin_dir[FN_REFLEN]; char opt_plugin_dir[FN_REFLEN];
LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]= const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
{ {
{ (char *)STRING_WITH_LEN("UDF") }, { (char *)STRING_WITH_LEN("UDF") },
{ (char *)STRING_WITH_LEN("STORAGE ENGINE") }, { (char *)STRING_WITH_LEN("STORAGE ENGINE") },
...@@ -63,7 +63,7 @@ static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM]; ...@@ -63,7 +63,7 @@ static HASH plugin_hash[MYSQL_MAX_PLUGIN_TYPE_NUM];
static rw_lock_t THR_LOCK_plugin; static rw_lock_t THR_LOCK_plugin;
static bool initialized= 0; static bool initialized= 0;
static struct st_plugin_dl *plugin_dl_find(LEX_STRING *dl) static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl)
{ {
uint i; uint i;
DBUG_ENTER("plugin_dl_find"); DBUG_ENTER("plugin_dl_find");
...@@ -112,7 +112,7 @@ static inline void free_plugin_mem(struct st_plugin_dl *p) ...@@ -112,7 +112,7 @@ static inline void free_plugin_mem(struct st_plugin_dl *p)
my_free((gptr)p->plugins, MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
} }
static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
{ {
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
char dlpath[FN_REFLEN]; char dlpath[FN_REFLEN];
...@@ -294,7 +294,7 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report) ...@@ -294,7 +294,7 @@ static st_plugin_dl *plugin_dl_add(LEX_STRING *dl, int report)
} }
static void plugin_dl_del(LEX_STRING *dl) static void plugin_dl_del(const LEX_STRING *dl)
{ {
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
uint i; uint i;
...@@ -322,7 +322,7 @@ static void plugin_dl_del(LEX_STRING *dl) ...@@ -322,7 +322,7 @@ static void plugin_dl_del(LEX_STRING *dl)
} }
static struct st_plugin_int *plugin_find_internal(LEX_STRING *name, int type) static struct st_plugin_int *plugin_find_internal(const LEX_STRING *name, int type)
{ {
uint i; uint i;
DBUG_ENTER("plugin_find_internal"); DBUG_ENTER("plugin_find_internal");
...@@ -345,7 +345,7 @@ static struct st_plugin_int *plugin_find_internal(LEX_STRING *name, int type) ...@@ -345,7 +345,7 @@ static struct st_plugin_int *plugin_find_internal(LEX_STRING *name, int type)
} }
my_bool plugin_is_ready(LEX_STRING *name, int type) my_bool plugin_is_ready(const LEX_STRING *name, int type)
{ {
my_bool rc= FALSE; my_bool rc= FALSE;
struct st_plugin_int *plugin; struct st_plugin_int *plugin;
...@@ -359,7 +359,7 @@ my_bool plugin_is_ready(LEX_STRING *name, int type) ...@@ -359,7 +359,7 @@ my_bool plugin_is_ready(LEX_STRING *name, int type)
} }
struct st_plugin_int *plugin_lock(LEX_STRING *name, int type) struct st_plugin_int *plugin_lock(const LEX_STRING *name, int type)
{ {
struct st_plugin_int *rc; struct st_plugin_int *rc;
DBUG_ENTER("plugin_lock"); DBUG_ENTER("plugin_lock");
...@@ -396,7 +396,7 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin) ...@@ -396,7 +396,7 @@ static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
struct st_plugin_int *)); struct st_plugin_int *));
} }
static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report) static my_bool plugin_add(const LEX_STRING *name, const LEX_STRING *dl, int report)
{ {
struct st_plugin_int tmp; struct st_plugin_int tmp;
struct st_mysql_plugin *plugin; struct st_mysql_plugin *plugin;
...@@ -479,7 +479,7 @@ static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report) ...@@ -479,7 +479,7 @@ static my_bool plugin_add(LEX_STRING *name, LEX_STRING *dl, int report)
} }
static void plugin_del(LEX_STRING *name) static void plugin_del(const LEX_STRING *name)
{ {
uint i; uint i;
struct st_plugin_int *plugin; struct st_plugin_int *plugin;
...@@ -811,7 +811,7 @@ void plugin_free(void) ...@@ -811,7 +811,7 @@ void plugin_free(void)
} }
my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl) my_bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl)
{ {
TABLE_LIST tables; TABLE_LIST tables;
TABLE *table; TABLE *table;
...@@ -866,7 +866,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl) ...@@ -866,7 +866,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl)
} }
my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name) my_bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name)
{ {
TABLE *table; TABLE *table;
TABLE_LIST tables; TABLE_LIST tables;
......
...@@ -66,15 +66,15 @@ typedef int (*plugin_type_init)(struct st_plugin_int *); ...@@ -66,15 +66,15 @@ typedef int (*plugin_type_init)(struct st_plugin_int *);
extern char *opt_plugin_dir_ptr; extern char *opt_plugin_dir_ptr;
extern char opt_plugin_dir[FN_REFLEN]; extern char opt_plugin_dir[FN_REFLEN];
extern LEX_STRING plugin_type_names[]; extern const LEX_STRING plugin_type_names[];
extern int plugin_init(void); extern int plugin_init(void);
extern void plugin_load(void); extern void plugin_load(void);
extern void plugin_free(void); extern void plugin_free(void);
extern my_bool plugin_is_ready(LEX_STRING *name, int type); extern my_bool plugin_is_ready(const LEX_STRING *name, int type);
extern st_plugin_int *plugin_lock(LEX_STRING *name, int type); extern st_plugin_int *plugin_lock(const LEX_STRING *name, int type);
extern void plugin_unlock(struct st_plugin_int *plugin); extern void plugin_unlock(struct st_plugin_int *plugin);
extern my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl); extern my_bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl);
extern my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name); extern my_bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name);
extern my_bool plugin_register_builtin(struct st_mysql_plugin *plugin); extern my_bool plugin_register_builtin(struct st_mysql_plugin *plugin);
......
...@@ -438,6 +438,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, ...@@ -438,6 +438,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
uint col_access=thd->col_access; uint col_access=thd->col_access;
#endif #endif
TABLE_LIST table_list; TABLE_LIST table_list;
char tbbuff[FN_REFLEN];
DBUG_ENTER("mysql_find_files"); DBUG_ENTER("mysql_find_files");
if (wild && !wild[0]) if (wild && !wild[0])
...@@ -454,6 +455,8 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, ...@@ -454,6 +455,8 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
VOID(tablename_to_filename(tmp_file_prefix, tbbuff, sizeof(tbbuff)));
for (i=0 ; i < (uint) dirp->number_off_files ; i++) for (i=0 ; i < (uint) dirp->number_off_files ; i++)
{ {
char uname[NAME_LEN*3+1]; /* Unencoded name */ char uname[NAME_LEN*3+1]; /* Unencoded name */
...@@ -491,7 +494,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, ...@@ -491,7 +494,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
{ {
// Return only .frm files which aren't temp files. // Return only .frm files which aren't temp files.
if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) || if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
is_prefix(file->name,tmp_file_prefix)) is_prefix(file->name,tbbuff))
continue; continue;
*ext=0; *ext=0;
VOID(filename_to_tablename(file->name, uname, sizeof(uname))); VOID(filename_to_tablename(file->name, uname, sizeof(uname)));
......
...@@ -30,7 +30,7 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info) ...@@ -30,7 +30,7 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info)
*/ */
if (hton == NULL || hton->state != SHOW_OPTION_YES) if (hton == NULL || hton->state != SHOW_OPTION_YES)
{ {
hton= ha_resolve_by_legacy_type(thd, DB_TYPE_DEFAULT); hton= ha_default_handlerton(thd);
if (ts_info->storage_engine != 0) if (ts_info->storage_engine != 0)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
ER_WARN_USING_OTHER_HANDLER, ER_WARN_USING_OTHER_HANDLER,
......
...@@ -111,6 +111,7 @@ byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end, ...@@ -111,6 +111,7 @@ byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end,
FT_WORD *word, MYSQL_FTPARSER_BOOLEAN_INFO *param) FT_WORD *word, MYSQL_FTPARSER_BOOLEAN_INFO *param)
{ {
byte *doc=*start; byte *doc=*start;
int ctype;
uint mwc, length, mbl; uint mwc, length, mbl;
param->yesno=(FTB_YES==' ') ? 1 : (param->quot != 0); param->yesno=(FTB_YES==' ') ? 1 : (param->quot != 0);
...@@ -119,9 +120,11 @@ byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end, ...@@ -119,9 +120,11 @@ byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end,
while (doc<end) while (doc<end)
{ {
for (;doc<end;doc++) for (; doc < end; doc+= (mbl > 0 ? mbl : 1))
{ {
if (true_word_char(cs,*doc)) break; mbl= cs->cset->ctype(cs, &ctype, (uchar*)doc, (uchar*)end);
if (true_word_char(ctype, *doc))
break;
if (*doc == FTB_RQUOT && param->quot) if (*doc == FTB_RQUOT && param->quot)
{ {
param->quot=doc; param->quot=doc;
...@@ -155,14 +158,16 @@ byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end, ...@@ -155,14 +158,16 @@ byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end,
} }
mwc=length=0; mwc=length=0;
for (word->pos=doc; doc<end; length++, mbl=my_mbcharlen(cs, *(uchar *)doc), doc+=(mbl ? mbl : 1)) for (word->pos= doc; doc < end; length++, doc+= (mbl > 0 ? mbl : 1))
if (true_word_char(cs,*doc)) {
mbl= cs->cset->ctype(cs, &ctype, (uchar*)doc, (uchar*)end);
if (true_word_char(ctype, *doc))
mwc=0; mwc=0;
else if (!misc_word_char(*doc) || mwc) else if (!misc_word_char(*doc) || mwc)
break; break;
else else
mwc++; mwc++;
}
param->prev='A'; /* be sure *prev is true_word_char */ param->prev='A'; /* be sure *prev is true_word_char */
word->len= (uint)(doc-word->pos) - mwc; word->len= (uint)(doc-word->pos) - mwc;
if ((param->trunc=(doc<end && *doc == FTB_TRUNC))) if ((param->trunc=(doc<end && *doc == FTB_TRUNC)))
...@@ -197,24 +202,31 @@ byte ft_simple_get_word(CHARSET_INFO *cs, byte **start, const byte *end, ...@@ -197,24 +202,31 @@ byte ft_simple_get_word(CHARSET_INFO *cs, byte **start, const byte *end,
{ {
byte *doc= *start; byte *doc= *start;
uint mwc, length, mbl; uint mwc, length, mbl;
int ctype;
DBUG_ENTER("ft_simple_get_word"); DBUG_ENTER("ft_simple_get_word");
do do
{ {
for (;; doc++) for (;; doc+= (mbl > 0 ? mbl : 1))
{ {
if (doc >= end) DBUG_RETURN(0); if (doc >= end)
if (true_word_char(cs, *doc)) break; DBUG_RETURN(0);
mbl= cs->cset->ctype(cs, &ctype, (uchar*)doc, (uchar*)end);
if (true_word_char(ctype, *doc))
break;
} }
mwc= length= 0; mwc= length= 0;
for (word->pos=doc; doc<end; length++, mbl=my_mbcharlen(cs, *(uchar *)doc), doc+=(mbl ? mbl : 1)) for (word->pos= doc; doc < end; length++, doc+= (mbl > 0 ? mbl : 1))
if (true_word_char(cs,*doc)) {
mbl= cs->cset->ctype(cs, &ctype, (uchar*)doc, (uchar*)end);
if (true_word_char(ctype, *doc))
mwc= 0; mwc= 0;
else if (!misc_word_char(*doc) || mwc) else if (!misc_word_char(*doc) || mwc)
break; break;
else else
mwc++; mwc++;
}
word->len= (uint)(doc-word->pos) - mwc; word->len= (uint)(doc-word->pos) - mwc;
......
...@@ -174,11 +174,6 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2) ...@@ -174,11 +174,6 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2)
FT_SEG_ITERATOR ftsi1, ftsi2; FT_SEG_ITERATOR ftsi1, ftsi2;
CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset; CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset;
DBUG_ENTER("_mi_ft_cmp"); DBUG_ENTER("_mi_ft_cmp");
#ifndef MYSQL_HAS_TRUE_CTYPE_IMPLEMENTATION
if (cs->mbmaxlen > 1)
DBUG_RETURN(THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT);
#endif
_mi_ft_segiterator_init(info, keynr, rec1, &ftsi1); _mi_ft_segiterator_init(info, keynr, rec1, &ftsi1);
_mi_ft_segiterator_init(info, keynr, rec2, &ftsi2); _mi_ft_segiterator_init(info, keynr, rec2, &ftsi2);
......
...@@ -24,9 +24,10 @@ ...@@ -24,9 +24,10 @@
#include <queues.h> #include <queues.h>
#include <mysql/plugin.h> #include <mysql/plugin.h>
#define true_word_char(s,X) (my_isalnum(s,X) || (X)=='_') #define true_word_char(ctype, character) \
((ctype) & (_MY_U | _MY_L | _MY_NMR) || \
(character) == '_')
#define misc_word_char(X) 0 #define misc_word_char(X) 0
#define word_char(s,X) (true_word_char(s,X) || misc_word_char(X))
#define FT_MAX_WORD_LEN_FOR_SORT 31 #define FT_MAX_WORD_LEN_FOR_SORT 31
......
...@@ -453,25 +453,24 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) ...@@ -453,25 +453,24 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
if ((uint) share->base.auto_key -1 == key) if ((uint) share->base.auto_key -1 == key)
{ {
/* Check that auto_increment key is bigger than max key value */ /* Check that auto_increment key is bigger than max key value */
ulonglong save_auto_value=info->s->state.auto_increment; ulonglong auto_increment;
info->s->state.auto_increment=0;
info->lastinx=key; info->lastinx=key;
_mi_read_key_record(info, 0L, info->rec_buff); _mi_read_key_record(info, 0L, info->rec_buff);
update_auto_increment(info, info->rec_buff); auto_increment= retrieve_auto_increment(info, info->rec_buff);
if (info->s->state.auto_increment > save_auto_value) if (auto_increment > info->s->state.auto_increment)
{ {
mi_check_print_warning(param, mi_check_print_warning(param, "Auto-increment value: %s is smaller "
"Auto-increment value: %s is smaller than max used value: %s", "than max used value: %s",
llstr(save_auto_value,buff2), llstr(info->s->state.auto_increment,buff2),
llstr(info->s->state.auto_increment, buff)); llstr(auto_increment, buff));
} }
if (param->testflag & T_AUTO_INC) if (param->testflag & T_AUTO_INC)
{ {
set_if_bigger(info->s->state.auto_increment, set_if_bigger(info->s->state.auto_increment,
param->auto_increment_value); auto_increment);
set_if_bigger(info->s->state.auto_increment,
param->auto_increment_value);
} }
else
info->s->state.auto_increment=save_auto_value;
/* Check that there isn't a row with auto_increment = 0 in the table */ /* Check that there isn't a row with auto_increment = 0 in the table */
mi_extra(info,HA_EXTRA_KEYREAD,0); mi_extra(info,HA_EXTRA_KEYREAD,0);
...@@ -481,8 +480,8 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) ...@@ -481,8 +480,8 @@ int chk_key(MI_CHECK *param, register MI_INFO *info)
{ {
/* Don't count this as a real warning, as myisamchk can't correct it */ /* Don't count this as a real warning, as myisamchk can't correct it */
uint save=param->warning_printed; uint save=param->warning_printed;
mi_check_print_warning(param, mi_check_print_warning(param, "Found row where the auto_increment "
"Found row where the auto_increment column has the value 0"); "column has the value 0");
param->warning_printed=save; param->warning_printed=save;
} }
mi_extra(info,HA_EXTRA_NO_KEYREAD,0); mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
...@@ -4124,11 +4123,10 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, ...@@ -4124,11 +4123,10 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
} }
else else
{ {
ulonglong auto_increment= (repair_only ? info->s->state.auto_increment : ulonglong auto_increment= retrieve_auto_increment(info, record);
param->auto_increment_value);
info->s->state.auto_increment=0;
update_auto_increment(info, record);
set_if_bigger(info->s->state.auto_increment,auto_increment); set_if_bigger(info->s->state.auto_increment,auto_increment);
if (!repair_only)
set_if_bigger(info->s->state.auto_increment, param->auto_increment_value);
} }
mi_extra(info,HA_EXTRA_NO_KEYREAD,0); mi_extra(info,HA_EXTRA_NO_KEYREAD,0);
my_free((char*) record, MYF(0)); my_free((char*) record, MYF(0));
......
...@@ -507,22 +507,21 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf) ...@@ -507,22 +507,21 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf)
return(-1); /* Wrong data to read */ return(-1); /* Wrong data to read */
} }
/* /*
Update auto_increment info Retrieve auto_increment info
SYNOPSIS SYNOPSIS
update_auto_increment() retrieve_auto_increment()
info MyISAM handler info MyISAM handler
record Row to update record Row to update
IMPLEMENTATION IMPLEMENTATION
Only replace the auto_increment value if it is higher than the previous For signed columns we don't retrieve the auto increment value if it's
one. For signed columns we don't update the auto increment value if it's
less than zero. less than zero.
*/ */
void update_auto_increment(MI_INFO *info,const byte *record) ulonglong retrieve_auto_increment(MI_INFO *info,const byte *record)
{ {
ulonglong value= 0; /* Store unsigned values here */ ulonglong value= 0; /* Store unsigned values here */
longlong s_value= 0; /* Store signed values here */ longlong s_value= 0; /* Store signed values here */
...@@ -587,6 +586,5 @@ void update_auto_increment(MI_INFO *info,const byte *record) ...@@ -587,6 +586,5 @@ void update_auto_increment(MI_INFO *info,const byte *record)
and if s_value == 0 then value will contain either s_value or the and if s_value == 0 then value will contain either s_value or the
correct value. correct value.
*/ */
set_if_bigger(info->s->state.auto_increment, return (s_value > 0) ? (ulonglong) s_value : value;
(s_value > 0) ? (ulonglong) s_value : value);
} }
...@@ -164,7 +164,8 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) ...@@ -164,7 +164,8 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
key_changed|= HA_STATE_CHANGED; /* Must update index file */ key_changed|= HA_STATE_CHANGED; /* Must update index file */
} }
if (auto_key_changed) if (auto_key_changed)
update_auto_increment(info,newrec); set_if_bigger(info->s->state.auto_increment,
retrieve_auto_increment(info, newrec));
if (share->calc_checksum) if (share->calc_checksum)
info->state->checksum+=(info->checksum - old_checksum); info->state->checksum+=(info->checksum - old_checksum);
......
...@@ -149,7 +149,8 @@ int mi_write(MI_INFO *info, byte *record) ...@@ -149,7 +149,8 @@ int mi_write(MI_INFO *info, byte *record)
info->state->checksum+=info->checksum; info->state->checksum+=info->checksum;
} }
if (share->base.auto_key) if (share->base.auto_key)
update_auto_increment(info,record); set_if_bigger(info->s->state.auto_increment,
retrieve_auto_increment(info, record));
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN | info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN |
HA_STATE_ROW_CHANGED); HA_STATE_ROW_CHANGED);
info->state->records++; info->state->records++;
......
...@@ -593,7 +593,7 @@ extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old, ...@@ -593,7 +593,7 @@ extern uint _mi_pack_key(MI_INFO *info,uint keynr,uchar *key,uchar *old,
extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf); extern int _mi_read_key_record(MI_INFO *info,my_off_t filepos,byte *buf);
extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos, extern int _mi_read_cache(IO_CACHE *info,byte *buff,my_off_t pos,
uint length,int re_read_if_possibly); uint length,int re_read_if_possibly);
extern void update_auto_increment(MI_INFO *info,const byte *record); extern ulonglong retrieve_auto_increment(MI_INFO *info,const byte *record);
extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**); extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**);
#define mi_get_rec_buff_ptr(info,buf) \ #define mi_get_rec_buff_ptr(info,buf) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment