Below is the list of changes that have just been committed into a local
5.0 repository of antony. When antony 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
1.1915 05/08/30 21:34:06 acurtis@stripped +16 -0
WL#2645
CHECK ... FOR UPGRADE
sql/table.h
1.112 05/08/30 21:33:22 acurtis@stripped +1 -0
wl2645 support for-upgrade
sql/table.cc
1.184 05/08/30 21:33:21 acurtis@stripped +13 -45
wl2645 support for-upgrade
sql/sql_yacc.yy
1.416 05/08/30 21:33:21 acurtis@stripped +21 -14
wl2645 support for-upgrade
sql/sql_table.cc
1.272 05/08/30 21:33:21 acurtis@stripped +177 -18
wl2645 support for-upgrade
sql/sql_base.cc
1.294 05/08/30 21:33:20 acurtis@stripped +28 -2
wl2645 support for-upgrade
sql/share/errmsg.txt
1.41 05/08/30 21:33:20 acurtis@stripped +2 -0
wl2645 support for-upgrade
sql/mysql_priv.h
1.346 05/08/30 21:33:19 acurtis@stripped +1 -0
wl2645 support for-upgrade
sql/lex.h
1.142 05/08/30 21:33:19 acurtis@stripped +1 -0
wl2645 support for-upgrade
sql/handler.h
1.150 05/08/30 21:33:18 acurtis@stripped +11 -2
wl2645 support for-upgrade
sql/handler.cc
1.186 05/08/30 21:33:18 acurtis@stripped +136 -0
wl2645 support for-upgrade
sql/ha_myisam.cc
1.157 05/08/30 21:33:17 acurtis@stripped +5 -0
wl2645 support for-upgrade
sql/ha_innodb.cc
1.250 05/08/30 21:33:17 acurtis@stripped +4 -0
wl2645 support for-upgrade
sql/ha_berkeley.cc
1.156 05/08/30 21:33:17 acurtis@stripped +5 -1
wl2645 support for-upgrade
include/myisam.h
1.68 05/08/30 21:33:17 acurtis@stripped +3 -0
wl2645 support for-upgrade
include/my_base.h
1.71 05/08/30 21:33:17 acurtis@stripped +3 -1
wl2645 support for-upgrade
client/mysqlcheck.c
1.50 05/08/30 21:33:16 acurtis@stripped +19 -4
wl2645 support for-upgrade
# 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: acurtis
# Host: ltantony.xiphis.org
# Root: /usr/home/antony/work2/wl2645.2
--- 1.70/include/my_base.h 2005-06-24 18:34:50 +01:00
+++ 1.71/include/my_base.h 2005-08-30 21:33:17 +01:00
@@ -51,6 +51,7 @@
#define HA_OPEN_DELAY_KEY_WRITE 8 /* Don't update index */
#define HA_OPEN_ABORT_IF_CRASHED 16
#define HA_OPEN_FOR_REPAIR 32 /* open even if crashed */
+#define HA_OPEN_FOR_UPGRADE 64 /* open even if old vers */
/* The following is parameter to ha_rkey() how to use key */
@@ -313,8 +314,9 @@
#define HA_ERR_NO_CONNECTION 157 /* Could not connect to storage engine */
#define HA_ERR_NULL_IN_SPATIAL 158 /* NULLs are not supported in spatial index */
#define HA_ERR_TABLE_DEF_CHANGED 159 /* The table changed in storage engine */
+#define HA_ERR_TABLE_NEEDS_UPGRADE 160 /* The table changed in storage engine */
-#define HA_ERR_LAST 159 /*Copy last error nr.*/
+#define HA_ERR_LAST 160 /*Copy last error nr.*/
/* Add error numbers before HA_ERR_LAST and change it accordingly. */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
--- 1.67/include/myisam.h 2005-07-19 13:13:36 +01:00
+++ 1.68/include/myisam.h 2005-08-30 21:33:17 +01:00
@@ -365,6 +365,9 @@
*/
#define TT_USEFRM 1
+#ifndef TT_FOR_UPGRADE
+#define TT_FOR_UPGRADE 2
+#endif
#define O_NEW_INDEX 1 /* Bits set in out_flag */
#define O_NEW_DATA 2
--- 1.155/sql/ha_berkeley.cc 2005-08-15 16:31:00 +01:00
+++ 1.156/sql/ha_berkeley.cc 2005-08-30 21:33:17 +01:00
@@ -2332,7 +2332,7 @@
{
DBUG_ENTER("ha_berkeley::check");
- DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
+ DBUG_RETURN(handler::check(thd, check_opt));
#ifdef NOT_YET
char name_buff[FN_REFLEN];
@@ -2344,6 +2344,10 @@
locking for this.
*/
+ if (check_opt->sql_flags & TT_FOR_UPGRADE)
+ {
+ DBUG_RETURN(handler::check(thd, check_opt));
+ }
/* We must open the file again to be able to check it! */
if ((error=db_create(&tmp_file, db_env, 0)))
{
--- 1.156/sql/ha_myisam.cc 2005-07-20 17:02:25 +01:00
+++ 1.157/sql/ha_myisam.cc 2005-08-30 21:33:17 +01:00
@@ -317,6 +317,11 @@
MYISAM_SHARE* share = file->s;
const char *old_proc_info=thd->proc_info;
+ if (check_opt->sql_flags & TT_FOR_UPGRADE)
+ {
+ return(handler::check(thd, check_opt));
+ }
+
thd->proc_info="Checking table";
myisamchk_init(¶m);
param.thd = thd;
--- 1.185/sql/handler.cc 2005-08-25 07:37:10 +01:00
+++ 1.186/sql/handler.cc 2005-08-30 21:33:18 +01:00
@@ -318,6 +318,7 @@
SETMSG(HA_ERR_TABLE_EXIST, ER(ER_TABLE_EXISTS_ERROR));
SETMSG(HA_ERR_NO_CONNECTION, "Could not connect to storage engine");
SETMSG(HA_ERR_TABLE_DEF_CHANGED, ER(ER_TABLE_DEF_CHANGED));
+ SETMSG(HA_ERR_TABLE_NEEDS_UPGRADE, ER(ER_TABLE_NEEDS_UPGRADE));
/* Register the error messages for use with my_error(). */
return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
@@ -1703,6 +1704,9 @@
case HA_ERR_TABLE_DEF_CHANGED:
textno=ER_TABLE_DEF_CHANGED;
break;
+ case HA_ERR_TABLE_NEEDS_UPGRADE:
+ textno=ER_TABLE_NEEDS_UPGRADE;
+ break;
case HA_ERR_NO_SUCH_TABLE:
{
/*
@@ -1769,6 +1773,138 @@
error == HA_ERR_NULL_IN_SPATIAL)
info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
DBUG_RETURN(table->file->errkey);
+}
+
+
+/*
+ Perform compatibility checks involving DECIMAL
+*/
+static bool upgrade_check_bad_decimal(TABLE *table)
+{
+ bool needs_upgrade= 0;
+ if (table && table->s)
+ {
+ Field** field;
+ KEY *keyinfo;
+ KEY_PART_INFO *keypart;
+ uint i,j;
+
+ for (field= table->field, i=0;
+ i < table->s->fields && !needs_upgrade;
+ i++,field++)
+ {
+ if ((*field)->type() == FIELD_TYPE_NEWDECIMAL &&
+ table->s->mysql_version == 0)
+ {
+ Field_new_decimal *fld= (Field_new_decimal *)(*field);
+ needs_upgrade= 1;
+ /*
+ Fix pack length of old decimal values from 5.0.3 -> 5.0.4
+ The difference is that in the old version we stored precision
+ in the .frm table while we now store the display_length
+ */
+ fld->field_length= my_decimal_precision_to_length(fld->field_length,
+ fld->dec, fld->unsigned_flag);
+ fld->precision= my_decimal_length_to_precision(fld->field_length,
+ fld->dec, fld->unsigned_flag);
+ fld->bin_size= my_decimal_get_binary_size(fld->precision, fld->dec);
+ }
+ }
+
+ keyinfo= table->key_info;
+ for (i=0; i < table->s->keys; i++, keyinfo++)
+ {
+ keypart= keyinfo->key_part;
+ for (j=0 ; j < keyinfo->key_parts ; j++, keypart++)
+ {
+ if (!keypart->fieldnr)
+ continue;
+ Field *fld= table->field[keypart->fieldnr-1];
+ if (fld->type() == FIELD_TYPE_NEWDECIMAL &&
+ fld->key_length() != keypart->length)
+ {
+ needs_upgrade= 1;
+ /*
+ Fix a fatal error in decimal key handling that causes crashes
+ on Innodb. We fix it by reducing the key length so that
+ InnoDB never gets a too big key when searching.
+ This allows the end user to do an ALTER TABLE to fix the
+ error.
+ */
+ keyinfo->key_length-= (keypart->length - fld->key_length());
+ keypart->store_length-= (keypart->length - fld->key_length());
+ keypart->length= fld->key_length();
+ keypart->key_part_flag&= ~HA_PART_KEY_SEG;
+ keypart->field= fld;
+ }
+ }
+ }
+ }
+ return needs_upgrade;
+}
+
+
+/*
+ Performs checks upon the table.
+
+ SYNOPSIS
+ check()
+ thd thread doing CHECK TABLE operation
+ check_opt options from the parser
+
+ NOTES
+ Subclasses which override ::check() should call the
+ superclass implementation instead of returning
+ HA_ADMIN_OK or HA_ADMIN_NOT_IMPLEMENTED
+
+ RETURN
+ HA_ADMIN_OK Successful upgrade
+ HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
+ HA_ADMIN_NOT_IMPLEMENTED
+*/
+int handler::check(THD* thd, HA_CHECK_OPT* check_opt)
+{
+ if (check_opt->sql_flags & TT_FOR_UPGRADE)
+ {
+ bool need_upgrade= 0;
+
+ if (upgrade_check_bad_decimal(table))
+ need_upgrade= 1;
+
+ return need_upgrade || table->s->needs_upgrade
+ ? HA_ADMIN_NEEDS_UPGRADE : HA_ADMIN_OK;
+ }
+ return HA_ADMIN_NOT_IMPLEMENTED;
+}
+
+
+/*
+ Performs upgrade of table.
+
+ SYNOPSIS
+ upgrade()
+ thd thread doing REPAIR TABLE operation
+ check_opt options from the parser
+
+ NOTES
+ Subclasses which override ::upgrade() should call the
+ superclass implementation instead of returning HA_ADMIN_OK
+
+ RETURN
+ HA_ADMIN_OK Successful upgrade
+ HA_ADMIN_ALREADY_DONE Already done, nothing to do
+ HA_ADMIN_TRY_ALTER_FORCE ALTER TABLE xxx FORCE is required
+*/
+int handler::upgrade(THD *thd, HA_CHECK_OPT* check_opt)
+{
+ bool needs_alter_force= 0;
+ if (table && table->s->mysql_version >= MYSQL_VERSION_ID)
+ return HA_ADMIN_ALREADY_DONE;
+
+ if (upgrade_check_bad_decimal(table))
+ needs_alter_force= 1;
+
+ return needs_alter_force ? HA_ADMIN_TRY_ALTER_FORCE : HA_ADMIN_OK;
}
--- 1.149/sql/handler.h 2005-08-30 10:39:17 +01:00
+++ 1.150/sql/handler.h 2005-08-30 21:33:18 +01:00
@@ -45,6 +45,8 @@
#define HA_ADMIN_REJECT -6
#define HA_ADMIN_TRY_ALTER -7
#define HA_ADMIN_WRONG_CHECKSUM -8
+#define HA_ADMIN_NEEDS_UPGRADE -9
+#define HA_ADMIN_TRY_ALTER_FORCE -10
/* Bits in table_flags() to show what database can do */
@@ -417,6 +419,10 @@
/* Forward declaration for condition pushdown to storage engine */
typedef class Item COND;
+#ifndef TT_FOR_UPGRADE
+#define TT_FOR_UPGRADE 2
+#endif
+
typedef struct st_ha_check_opt
{
ulong sort_buffer_size;
@@ -663,8 +669,8 @@
virtual void update_create_info(HA_CREATE_INFO *create_info) {}
/* admin commands - called from mysql_admin_table */
- virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
- { return HA_ADMIN_NOT_IMPLEMENTED; }
+ virtual int check(THD* thd, HA_CHECK_OPT* check_opt);
+ virtual int upgrade(THD* thd, HA_CHECK_OPT* check_opt);
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
/*
@@ -686,6 +692,7 @@
/* end of the list of admin commands */
virtual bool check_and_repair(THD *thd) { return HA_ERR_WRONG_COMMAND; }
+ virtual bool check_and_upgrade(THD *thd) { return HA_ERR_WRONG_COMMAND; }
virtual int dump(THD* thd, int fd = -1) { return HA_ERR_WRONG_COMMAND; }
virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
@@ -743,6 +750,8 @@
virtual uint checksum() const { return 0; }
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; }
+ virtual bool auto_upgrade() const { return 0; }
+ virtual bool needs_upgrade() const { return 0; }
/*
default rename_table() and delete_table() rename/delete files with a
--- 1.141/sql/lex.h 2005-08-25 14:39:00 +01:00
+++ 1.142/sql/lex.h 2005-08-30 21:33:19 +01:00
@@ -513,6 +513,7 @@
{ "UNSIGNED", SYM(UNSIGNED)},
{ "UNTIL", SYM(UNTIL_SYM)},
{ "UPDATE", SYM(UPDATE_SYM)},
+ { "UPGRADE", SYM(UPGRADE_SYM)},
{ "USAGE", SYM(USAGE)},
{ "USE", SYM(USE_SYM)},
{ "USER", SYM(USER)},
--- 1.345/sql/mysql_priv.h 2005-08-30 10:39:17 +01:00
+++ 1.346/sql/mysql_priv.h 2005-08-30 21:33:19 +01:00
@@ -706,6 +706,7 @@
bool ignore,
ALTER_INFO *alter_info, bool do_send_ok);
bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
+bool mysql_alter_table_force(THD *thd, TABLE_LIST *table_list, bool do_send_ok);
bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
HA_CREATE_INFO *create_info,
Table_ident *src_table);
--- 1.293/sql/sql_base.cc 2005-08-24 22:22:52 +01:00
+++ 1.294/sql/sql_base.cc 2005-08-30 21:33:20 +01:00
@@ -1275,6 +1275,13 @@
table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
table_list->updatable= 1; // It is not derived table nor non-updatable VIEW
DBUG_ASSERT(table->key_read == 0);
+ if (table->s->needs_upgrade)
+ {
+ sql_print_error(ER(ER_TABLE_NEEDS_UPGRADE), table->s->table_name);
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_TABLE_NEEDS_UPGRADE,
+ ER(ER_TABLE_NEEDS_UPGRADE), table->s->table_name);
+ }
DBUG_RETURN(table);
}
@@ -1677,7 +1684,7 @@
thd->open_options, entry, table_desc, mem_root))))
{
- if (!entry->s || !entry->s->crashed)
+ if (!entry->s || !(entry->s->crashed || entry->s->needs_upgrade))
{
/*
Frm file could not be found on disk
@@ -1728,7 +1735,26 @@
pthread_mutex_unlock(&LOCK_open);
thd->clear_error(); // Clear error message
error= 0;
- if (openfrm(thd, path, alias,
+ if (entry->s->needs_upgrade &&
+ openfrm(thd, path, alias,
+ (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
+ HA_TRY_READ_ONLY),
+ READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
+ ha_open_options | HA_OPEN_FOR_UPGRADE,
+ entry) || ! entry->file ||
+ (entry->file->needs_upgrade() && entry->file->check_and_upgrade(thd)))
+ {
+ /* Give right error message */
+ thd->clear_error();
+ my_error(ER_NOT_KEYFILE, MYF(0), name, my_errno);
+ sql_print_error("Couldn't upgrade table: %s.%s",db,name);
+ if (entry->file)
+ closefrm(entry);
+ error=1;
+ }
+ else
+ if (!entry->s->needs_upgrade &&
+ openfrm(thd, path, alias,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
--- 1.271/sql/sql_table.cc 2005-08-30 07:18:12 +01:00
+++ 1.272/sql/sql_table.cc 2005-08-30 21:33:21 +01:00
@@ -43,6 +43,8 @@
static bool prepare_blob_field(THD *thd, create_field *sql_field);
static bool check_engine(THD *thd, const char *table_name,
enum db_type *new_engine);
+static int post_upgrade_check(THD *thd, TABLE_LIST *tables,
+ HA_CHECK_OPT *check_opt);
/*
@@ -2108,7 +2110,9 @@
HA_CHECK_OPT *),
int (handler::*operator_func)(THD *,
HA_CHECK_OPT *),
- int (view_operator_func)(THD *, TABLE_LIST*))
+ int (view_operator_func)(THD *, TABLE_LIST*),
+ int (*post_func)(THD *, TABLE_LIST *,
+ HA_CHECK_OPT *))
{
TABLE_LIST *table, *save_next_global, *save_next_local;
SELECT_LEX *select= &thd->lex->select_lex;
@@ -2386,6 +2390,53 @@
system_charset_info);
break;
}
+ case HA_ADMIN_NEEDS_UPGRADE:
+ protocol->store("error", 5, system_charset_info);
+ protocol->store("Table upgrade required",22, system_charset_info);
+ fatal_error=1;
+ break;
+ case HA_ADMIN_TRY_ALTER_FORCE:
+ {
+ /*
+ This is used when handler::upgrade() answers
+ "try with alter force", so here we close the table,
+ then do an ALTER TABLE FORCE,
+ */
+ close_thread_tables(thd);
+ TABLE_LIST *save_next_local= table->next_local,
+ *save_next_global= table->next_global;
+ table->next_local= table->next_global= 0;
+ tmp_disable_binlog(thd); // binlogging is done by caller if wanted
+ result_code= mysql_alter_table_force(thd, table, 0);
+ reenable_binlog(thd);
+ if (result_code) // either mysql_alter_table_force failed
+ {
+ const char *err_msg;
+ if ((err_msg= thd->net.last_error))
+ {
+ if (!thd->vio_ok())
+ {
+ sql_print_error(err_msg);
+ }
+ else
+ {
+ /* Hijack the row already in-progress. */
+ protocol->store("error", 5, system_charset_info);
+ protocol->store(err_msg, system_charset_info);
+ (void)protocol->write();
+ /* Start off another row for HA_ADMIN_FAILED */
+ protocol->prepare_for_resend();
+ protocol->store(table_name, system_charset_info);
+ protocol->store(operator_name, system_charset_info);
+ }
+ }
+ }
+ result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
+ table->next_local= save_next_local;
+ table->next_global= save_next_global;
+ goto send_result_message;
+ }
+
default: // Probably HA_ADMIN_INTERNAL_ERROR
protocol->store("error", 5, system_charset_info);
@@ -2394,6 +2445,21 @@
fatal_error=1;
break;
}
+
+ if (post_func && result_code == HA_ADMIN_OK)
+ {
+ switch (post_func(thd, table, check_opt))
+ {
+ case 1: // error, message written to net
+ close_thread_tables(thd);
+ continue;
+ case -1: // error, message could be written to net
+ goto err;
+ default: // should be 0 otherwise
+ ;
+ }
+ }
+
if (fatal_error)
table->table->s->version=0; // Force close of table
else if (open_for_modify)
@@ -2426,7 +2492,7 @@
DBUG_ENTER("mysql_backup_table");
DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
"backup", TL_READ, 0, 0, 0, 0,
- &handler::backup, 0));
+ &handler::backup, 0, 0));
}
@@ -2436,19 +2502,27 @@
DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
"restore", TL_WRITE, 1, 1, 0,
&prepare_for_restore,
- &handler::restore, 0));
+ &handler::restore, 0, 0));
}
bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
{
+ bool result;
DBUG_ENTER("mysql_repair_table");
- DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
- "repair", TL_WRITE, 1,
- test(check_opt->sql_flags & TT_USEFRM),
- HA_OPEN_FOR_REPAIR,
- &prepare_for_repair,
- &handler::repair, 0));
+
+ if (test(check_opt->sql_flags & TT_FOR_UPGRADE))
+ result= mysql_admin_table(thd, tables, check_opt,
+ "upgrade", TL_WRITE, 1, 0,
+ HA_OPEN_FOR_UPGRADE, 0,
+ &handler::upgrade, 0, &post_upgrade_check);
+ else
+ result= mysql_admin_table(thd, tables, check_opt,
+ "repair", TL_WRITE, 1,
+ test(check_opt->sql_flags & TT_USEFRM),
+ HA_OPEN_FOR_REPAIR, &prepare_for_repair,
+ &handler::repair, 0, 0);
+ DBUG_RETURN(result);
}
@@ -2457,7 +2531,7 @@
DBUG_ENTER("mysql_optimize_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
"optimize", TL_WRITE, 1,0,0,0,
- &handler::optimize, 0));
+ &handler::optimize, 0, 0));
}
@@ -2493,7 +2567,7 @@
check_opt.key_cache= key_cache;
DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
"assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
- 0, 0, &handler::assign_to_keycache, 0));
+ 0, 0, &handler::assign_to_keycache, 0, 0));
}
@@ -2554,7 +2628,7 @@
DBUG_ENTER("mysql_preload_keys");
DBUG_RETURN(mysql_admin_table(thd, tables, 0,
"preload_keys", TL_READ, 0, 0, 0, 0,
- &handler::preload_keys, 0));
+ &handler::preload_keys, 0, 0));
}
@@ -2742,7 +2816,46 @@
DBUG_ENTER("mysql_analyze_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
"analyze", lock_type, 1, 0, 0, 0,
- &handler::analyze, 0));
+ &handler::analyze, 0, 0));
+}
+
+
+/*
+ If the upgrade checks do not signal any error, this function
+ is called and will silently update the frm mysql version.
+*/
+static int post_upgrade_check(THD *thd, TABLE_LIST *tables,
+ HA_CHECK_OPT *check_opt)
+{
+ TABLE *table= tables->table;
+ Protocol *protocol= thd->protocol;
+ int error= 0;
+ if (table && table->s->mysql_version != MYSQL_VERSION_ID)
+ {
+ char path[IO_SIZE];
+ pthread_mutex_lock(&LOCK_open);
+ if (build_table_path(path, sizeof(path), tables->db,
+ (lower_case_table_names == 2) ?
+ tables->alias : tables->table_name,
+ reg_ext) != 0)
+ {
+ File file;
+ uchar fileinfo[64];
+ if ((file= my_open(path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
+ {
+ uint tmp= MYSQL_VERSION_ID;
+ if (!my_pread(file,(byte*) fileinfo,64,0L,MYF(MY_NABP)))
+ {
+ int4store(fileinfo+51, tmp);
+ if (!my_pwrite(file,(byte*) fileinfo,64,0L,MYF_RW))
+ table->s->mysql_version= MYSQL_VERSION_ID;
+ }
+ VOID(my_close(file,MYF(MY_WME)));
+ }
+ }
+ pthread_mutex_unlock(&LOCK_open);
+ }
+ return(error);
}
@@ -2753,12 +2866,22 @@
#else
thr_lock_type lock_type = TL_READ_NO_INSERT;
#endif
-
+ bool result;
DBUG_ENTER("mysql_check_table");
- DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
- "check", lock_type,
- 0, HA_OPEN_FOR_REPAIR, 0, 0,
- &handler::check, &view_checksum));
+
+ if (test(check_opt->sql_flags & TT_FOR_UPGRADE))
+ result= mysql_admin_table(thd, tables, check_opt,
+ "check", lock_type,
+ 0, HA_OPEN_FOR_UPGRADE, 0, 0,
+ &handler::check,
+ 0, &post_upgrade_check);
+ else
+ result= mysql_admin_table(thd, tables, check_opt,
+ "check", lock_type,
+ 0, HA_OPEN_FOR_REPAIR, 0, 0,
+ &handler::check,
+ &view_checksum, 0);
+ DBUG_RETURN(result);
}
@@ -4029,6 +4152,42 @@
table_list, lex->create_list,
lex->key_list, 0, (ORDER *) 0,
DUP_ERROR, 0, &lex->alter_info, do_send_ok));
+}
+
+
+/*
+ Simulates an invocation of "ALTER TABLE xxx FORCE"
+ by calling mysql_alter_table().
+
+ SYNOPSIS
+ mysql_alter_table_force()
+ thd Thread handler
+ tables Tables to recreate
+ do_send_ok If we should send_ok() or leave it to caller
+
+ RETURN
+ Like mysql_alter_table().
+*/
+bool mysql_alter_table_force(THD *thd, TABLE_LIST *table_list,
+ bool do_send_ok)
+{
+ HA_CREATE_INFO create_info;
+ ALTER_INFO alter_info;
+ List<create_field> fld_list;
+ List<Key> key_list;
+ DBUG_ENTER("mysql_recreate_table");
+
+ bzero((char*) &create_info,sizeof(create_info));
+ create_info.db_type= DB_TYPE_DEFAULT;
+ create_info.default_table_charset= NULL;
+ create_info.row_type= ROW_TYPE_NOT_USED;
+ alter_info.reset();
+ alter_info.flags= ALTER_FORCE;
+
+ DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
+ table_list, fld_list,
+ key_list, 0, (ORDER *)0,
+ DUP_ERROR, 0, &alter_info, do_send_ok));
}
--- 1.415/sql/sql_yacc.yy 2005-08-29 20:10:49 +01:00
+++ 1.416/sql/sql_yacc.yy 2005-08-30 21:33:21 +01:00
@@ -626,7 +626,7 @@
%token UNTIL_SYM
%token UNTIL_SYM
%token UPDATE_SYM
-%token UPDATE_SYM
+%token UPGRADE_SYM
%token USAGE
%token USER
%token USE_FRM
@@ -699,7 +699,7 @@
type int_type real_type order_dir lock_option
udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_no_write_to_binlog
- delete_option opt_temporary all_or_any opt_distinct
+ on_delete_option opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options spatial_type union_option
start_transaction_opts opt_chain opt_release
union_opt select_derived_init option_type2
@@ -808,8 +808,8 @@
grant revoke set lock unlock string_list field_options field_option
field_opt_list opt_binary table_lock_list table_lock
ref_list opt_on_delete opt_on_delete_list opt_on_delete_item use
- opt_delete_options opt_delete_option varchar nchar nvarchar
- opt_outer table_list table_name opt_option opt_place
+ opt_delete_options delete_options_list delete_option varchar nchar
+ nvarchar opt_outer table_list table_name opt_option opt_place
opt_attribute opt_attribute_list attribute column_list column_list_id
opt_column_list grant_privileges grant_ident grant_list grant_option
object_privilege object_privilege_list user_list rename_list
@@ -2653,12 +2653,12 @@
create_table_options_space_separated:
create_table_option
- | create_table_option create_table_options_space_separated;
+ | create_table_options_space_separated create_table_option;
create_table_options:
create_table_option
- | create_table_option create_table_options
- | create_table_option ',' create_table_options;
+ | create_table_options create_table_option
+ | create_table_options ',' create_table_option;
create_table_option:
ENGINE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; }
@@ -3260,13 +3260,13 @@
| opt_on_delete_item {};
opt_on_delete_item:
- ON DELETE_SYM delete_option { Lex->fk_delete_opt= $3; }
- | ON UPDATE_SYM delete_option { Lex->fk_update_opt= $3; }
+ ON DELETE_SYM on_delete_option { Lex->fk_delete_opt= $3; }
+ | ON UPDATE_SYM on_delete_option { Lex->fk_update_opt= $3; }
| MATCH FULL { Lex->fk_match_option= foreign_key::FK_MATCH_FULL; }
| MATCH PARTIAL { Lex->fk_match_option= foreign_key::FK_MATCH_PARTIAL; }
| MATCH SIMPLE_SYM { Lex->fk_match_option= foreign_key::FK_MATCH_SIMPLE; };
-delete_option:
+on_delete_option:
RESTRICT { $$= (int) foreign_key::FK_OPTION_RESTRICT; }
| CASCADE { $$= (int) foreign_key::FK_OPTION_CASCADE; }
| SET NULL_SYM { $$= (int) foreign_key::FK_OPTION_SET_NULL; }
@@ -3792,11 +3792,12 @@
opt_mi_repair_type:
/* empty */ { Lex->check_opt.flags = T_MEDIUM; }
+ | UPGRADE_SYM { Lex->check_opt.sql_flags= TT_FOR_UPGRADE; }
| mi_repair_types {};
mi_repair_types:
mi_repair_type {}
- | mi_repair_type mi_repair_types {};
+ | mi_repair_types mi_repair_type {};
mi_repair_type:
QUICK { Lex->check_opt.flags|= T_QUICK; }
@@ -3834,11 +3835,12 @@
opt_mi_check_type:
/* empty */ { Lex->check_opt.flags = T_MEDIUM; }
+ | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags |= TT_FOR_UPGRADE; }
| mi_check_types {};
mi_check_types:
mi_check_type {}
- | mi_check_type mi_check_types {};
+ | mi_check_types mi_check_type {};
mi_check_type:
QUICK { Lex->check_opt.flags|= T_QUICK; }
@@ -6344,9 +6346,13 @@
opt_delete_options:
/* empty */ {}
- | opt_delete_option opt_delete_options {};
+ | delete_options_list {};
+
+delete_options_list:
+ delete_option {}
+ | delete_options_list delete_option {};
-opt_delete_option:
+delete_option:
QUICK { Select->options|= OPTION_QUICK; }
| LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
| IGNORE_SYM { Lex->ignore= 1; };
@@ -7722,6 +7728,7 @@
| UNDEFINED_SYM {}
| UNKNOWN_SYM {}
| UNTIL_SYM {}
+ | UPGRADE_SYM {}
| USER {}
| USE_FRM {}
| VARIABLES {}
--- 1.183/sql/table.cc 2005-08-23 16:15:46 +01:00
+++ 1.184/sql/table.cc 2005-08-30 21:33:21 +01:00
@@ -554,26 +554,6 @@
unhex_type2(interval);
}
-#ifndef TO_BE_DELETED_ON_PRODUCTION
- if (field_type == FIELD_TYPE_NEWDECIMAL && !share->mysql_version)
- {
- /*
- Fix pack length of old decimal values from 5.0.3 -> 5.0.4
- The difference is that in the old version we stored precision
- in the .frm table while we now store the display_length
- */
- uint decimals= f_decimals(pack_flag);
- field_length= my_decimal_precision_to_length(field_length,
- decimals,
- f_is_dec(pack_flag) == 0);
- sql_print_error("Found incompatible DECIMAL field '%s' in %s; Please do \"ALTER TABLE '%s' FORCE\" to fix it!", share->fieldnames.type_names[i], name, share->table_name);
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_CRASHED_ON_USAGE,
- "Found incompatible DECIMAL field '%s' in %s; Please do \"ALTER TABLE '%s' FORCE\" to fix it!", share->fieldnames.type_names[i], name, share->table_name);
- share->crashed= 1; // Marker for CHECK TABLE
- }
-#endif
-
*field_ptr=reg_field=
make_field(record+recpos,
(uint32) field_length,
@@ -734,29 +714,6 @@
}
if (field->key_length() != key_part->length)
{
-#ifndef TO_BE_DELETED_ON_PRODUCTION
- if (field->type() == FIELD_TYPE_NEWDECIMAL)
- {
- /*
- Fix a fatal error in decimal key handling that causes crashes
- on Innodb. We fix it by reducing the key length so that
- InnoDB never gets a too big key when searching.
- This allows the end user to do an ALTER TABLE to fix the
- error.
- */
- keyinfo->key_length-= (key_part->length - field->key_length());
- key_part->store_length-= (uint16)(key_part->length -
- field->key_length());
- key_part->length= (uint16)field->key_length();
- sql_print_error("Found wrong key definition in %s; Please do \"ALTER TABLE '%s' FORCE \" to fix it!", name, share->table_name);
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_CRASHED_ON_USAGE,
- "Found wrong key definition in %s; Please do \"ALTER TABLE '%s' FORCE\" to fix it!", name, share->table_name);
-
- share->crashed= 1; // Marker for CHECK TABLE
- goto to_be_deleted;
- }
-#endif
key_part->key_part_flag|= HA_PART_KEY_SEG;
if (!(field->flags & BLOB_FLAG))
{ // Create a new field
@@ -766,8 +723,6 @@
}
}
- to_be_deleted:
-
/*
If the field can be NULL, don't optimize away the test
key_part_column = expression from the WHERE clause
@@ -876,6 +831,11 @@
share->crashed= ((ha_err == HA_ERR_CRASHED_ON_USAGE) &&
outparam->file->auto_repair() &&
!(ha_open_flags & HA_OPEN_FOR_REPAIR));
+ /* Set a flag if the table needs upgrade and it can be auto. upgraded */
+ share->needs_upgrade=
+ ((ha_err == HA_ERR_TABLE_NEEDS_UPGRADE) &&
+ outparam->file->auto_upgrade() &&
+ !(ha_open_flags & HA_OPEN_FOR_UPGRADE));
if (ha_err == HA_ERR_NO_SUCH_TABLE)
{
@@ -894,6 +854,14 @@
}
share->db_low_byte_first= outparam->file->low_byte_first();
+ if (share->mysql_version != MYSQL_VERSION_ID)
+ {
+ HA_CHECK_OPT check_opt;
+ bzero(&check_opt, sizeof(check_opt));
+ check_opt.sql_flags= TT_FOR_UPGRADE;
+ if (outparam->file->check(thd, &check_opt) == HA_ADMIN_NEEDS_UPGRADE)
+ share->needs_upgrade= TRUE;
+ }
*root_ptr= old_root;
thd->status_var.opened_tables++;
#ifndef DBUG_OFF
--- 1.111/sql/table.h 2005-08-26 10:24:52 +01:00
+++ 1.112/sql/table.h 2005-08-30 21:33:22 +01:00
@@ -165,6 +165,7 @@
my_bool crypted; /* If .frm file is crypted */
my_bool db_low_byte_first; /* Portable row format */
my_bool crashed;
+ my_bool needs_upgrade; /* Set if table data fmt is old */
my_bool is_view;
my_bool name_lock, replace_with_name_lock;
/*
--- 1.40/sql/share/errmsg.txt 2005-08-23 06:15:00 +01:00
+++ 1.41/sql/share/errmsg.txt 2005-08-30 21:33:20 +01:00
@@ -5399,3 +5399,5 @@
eng "Datetime function: %-.32s field overflow"
ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
eng "Can't update table '%-.64s' in stored function/trigger because it is already used by statement which invoked this stored function/trigger."
+ER_TABLE_NEEDS_UPGRADE
+ eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s` UPGRADE\" to fix it!"
--- 1.49/client/mysqlcheck.c 2005-08-26 13:45:18 +01:00
+++ 1.50/client/mysqlcheck.c 2005-08-30 21:33:16 +01:00
@@ -34,7 +34,7 @@
opt_compress = 0, opt_databases = 0, opt_fast = 0,
opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
- tty_password = 0, opt_frm = 0;
+ tty_password = 0, opt_frm = 0, opt_upgrade = 0;
static uint verbose = 0, opt_mysql_port=0;
static my_string opt_mysql_unix_port = 0;
static char *opt_password = 0, *current_user = 0,
@@ -98,6 +98,9 @@
{"fast",'F', "Check only tables that haven't been closed properly.",
(gptr*) &opt_fast, (gptr*) &opt_fast, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
0},
+ {"for-upgrade", 'U',
+ "Check the table for version dependent changes. May be used with auto-repair to correct tables requiring version dependent updates.",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"force", 'f', "Continue even if we get an sql-error.",
(gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0},
@@ -233,12 +236,14 @@
case 'a':
what_to_do = DO_ANALYZE;
break;
+ case 'C':
+ opt_check_only_changed = 1;
case 'c':
what_to_do = DO_CHECK;
break;
- case 'C':
+ case 'U':
what_to_do = DO_CHECK;
- opt_check_only_changed = 1;
+ opt_upgrade = 1;
break;
case 'I': /* Fall through */
case '?':
@@ -517,6 +522,11 @@
switch (what_to_do) {
case DO_CHECK:
op = "CHECK";
+ if (opt_upgrade)
+ {
+ end = strmov(end, " FOR UPGRADE");
+ break;
+ }
if (opt_quick) end = strmov(end, " QUICK");
if (opt_fast) end = strmov(end, " FAST");
if (opt_medium_check) end = strmov(end, " MEDIUM"); /* Default */
@@ -525,6 +535,11 @@
break;
case DO_REPAIR:
op = "REPAIR";
+ if (opt_upgrade)
+ {
+ end = strmov(end, " UPGRADE");
+ break;
+ }
if (opt_quick) end = strmov(end, " QUICK");
if (opt_extended) end = strmov(end, " EXTENDED");
if (opt_frm) end = strmov(end, " USE_FRM");
@@ -712,7 +727,7 @@
uint i;
if (!opt_silent && tables4repair.elements)
- puts("\nRepairing tables");
+ puts(opt_upgrade ? "\nUpgrading tables" :"\nRepairing tables");
what_to_do = DO_REPAIR;
for (i = 0; i < tables4repair.elements ; i++)
{
--- 1.249/sql/ha_innodb.cc 2005-08-30 10:39:17 +01:00
+++ 1.250/sql/ha_innodb.cc 2005-08-30 21:33:17 +01:00
@@ -5588,6 +5588,10 @@
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
ulint ret;
+ if (check_opt->sql_flags & TT_FOR_UPGRADE)
+ {
+ return(handler::check(thd, check_opt));
+ }
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx ==
(trx_t*) current_thd->ha_data[innobase_hton.slot]);
| Thread |
|---|
| • bk commit into 5.0 tree (acurtis:1.1915) | antony | 30 Aug |