summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
authorunknown <holyfoot@deer.(none)>2006-02-17 10:52:32 +0400
committerunknown <holyfoot@deer.(none)>2006-02-17 10:52:32 +0400
commitbf840404581d81fbb351f976a08a124d9be0b624 (patch)
treee1075b7c3e3c1d0a91edf078cf69906180661d4c /sql/handler.cc
parent74f6299efd3091e64f8eaf1c4b5ec979ed97ce03 (diff)
downloadmariadb-git-bf840404581d81fbb351f976a08a124d9be0b624.tar.gz
WL#2645 (CHECK TABLE FOR UPGRADE)
necessary implementation in the server mysql_upgrade script added client/mysqlcheck.c: --check-upgrade option added include/my_base.h: errcode added include/myisam.h: option added scripts/Makefile.am: mysql_upgrade script added sql/handler.cc: checks for old types/bugs added sql/handler.h: declarations regarding checks for upgrade sql/lex.h: sym added sql/share/errmsg.txt: error message added sql/slave.cc: now ha_repair is for public use sql/sql_table.cc: upgrade in ha_repair implemented sql/sql_yacc.yy: CHECK ... FOR UPGRADE added to syntax
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc152
1 files changed, 152 insertions, 0 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 4e128eb5938..006a0eb2407 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -425,6 +425,7 @@ static int ha_init_errors(void)
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);
@@ -1795,6 +1796,9 @@ void handler::print_error(int error, myf errflag)
my_error(ER_NO_SUCH_TABLE, MYF(0), db, table->alias);
break;
}
+ case HA_ERR_TABLE_NEEDS_UPGRADE:
+ textno=ER_TABLE_NEEDS_UPGRADE;
+ break;
default:
{
/* The error was "unknown" to this function.
@@ -1836,6 +1840,103 @@ bool handler::get_error_message(int error, String* buf)
}
+int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt)
+{
+ KEY *keyinfo, *keyend;
+ KEY_PART_INFO *keypart, *keypartend;
+
+ if (!table->s->mysql_version)
+ {
+ /* check for blob-in-key error */
+ keyinfo= table->key_info;
+ keyend= table->key_info + table->s->keys;
+ for (; keyinfo < keyend; keyinfo++)
+ {
+ keypart= keyinfo->key_part;
+ keypartend= keypart + keyinfo->key_parts;
+ for (; keypart < keypartend; keypart++)
+ {
+ if (!keypart->fieldnr)
+ continue;
+ Field *field= table->field[keypart->fieldnr-1];
+ if (field->type() == FIELD_TYPE_BLOB)
+ {
+ if (check_opt->sql_flags & TT_FOR_UPGRADE)
+ check_opt->flags= T_MEDIUM;
+ return HA_ADMIN_NEEDS_CHECK;
+ }
+ }
+ }
+ }
+ return check_for_upgrade(check_opt);
+}
+
+
+int handler::check_old_types()
+{
+ Field** field;
+
+ if (!table->s->mysql_version)
+ {
+ /* check for bad DECIMAL field */
+ for (field= table->field; (*field); field++)
+ {
+ if ((*field)->type() == FIELD_TYPE_NEWDECIMAL)
+ {
+ return HA_ADMIN_NEEDS_ALTER;
+ }
+ }
+ }
+ return 0;
+}
+
+
+static bool update_frm_version(TABLE *table, bool needs_lock)
+{
+ char path[FN_REFLEN];
+ File file;
+ int result= 1;
+ DBUG_ENTER("update_frm_version");
+
+ if (table->s->mysql_version != MYSQL_VERSION_ID)
+ DBUG_RETURN(0);
+
+ strxnmov(path, sizeof(path)-1, mysql_data_home, "/", table->s->db, "/",
+ table->s->table_name, reg_ext, NullS);
+ if (!unpack_filename(path, path))
+ DBUG_RETURN(1);
+
+ if (needs_lock)
+ pthread_mutex_lock(&LOCK_open);
+
+ if ((file= my_open(path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
+ {
+ uchar version[4];
+ char *key= table->s->table_cache_key;
+ uint key_length= table->s->key_length;
+ TABLE *entry;
+ HASH_SEARCH_STATE state;
+
+ int4store(version, MYSQL_VERSION_ID);
+
+ if ((result= my_pwrite(file,(byte*) version,4,51L,MYF_RW)))
+ goto err;
+
+ for (entry=(TABLE*) hash_first(&open_cache,(byte*) key,key_length, &state);
+ entry;
+ entry= (TABLE*) hash_next(&open_cache,(byte*) key,key_length, &state))
+ entry->s->mysql_version= MYSQL_VERSION_ID;
+ }
+err:
+ if (file >= 0)
+ VOID(my_close(file,MYF(MY_WME)));
+ if (needs_lock)
+ pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(result);
+}
+
+
+
/* Return key if error because of duplicated keys */
uint handler::get_dup_key(int error)
@@ -1903,6 +2004,57 @@ int handler::rename_table(const char * from, const char * to)
return error;
}
+
+/*
+ Performs checks upon the table.
+
+ SYNOPSIS
+ check()
+ thd thread doing CHECK TABLE operation
+ check_opt options from the parser
+
+ NOTES
+
+ RETURN
+ HA_ADMIN_OK Successful upgrade
+ HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
+ HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
+ HA_ADMIN_NOT_IMPLEMENTED
+*/
+
+int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
+{
+ int error;
+
+ if ((table->s->mysql_version >= MYSQL_VERSION_ID) &&
+ (check_opt->sql_flags & TT_FOR_UPGRADE))
+ return 0;
+
+ if (table->s->mysql_version < MYSQL_VERSION_ID)
+ {
+ if ((error= check_old_types()))
+ return error;
+ error= ha_check_for_upgrade(check_opt);
+ if (error && (error != HA_ADMIN_NEEDS_CHECK))
+ return error;
+ if (!error && (check_opt->sql_flags & TT_FOR_UPGRADE))
+ return 0;
+ }
+ if ((error= check(thd, check_opt)))
+ return error;
+ return update_frm_version(table, 0);
+}
+
+
+int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
+{
+ int result;
+ if ((result= repair(thd, check_opt)))
+ return result;
+ return update_frm_version(table, 0);
+}
+
+
/*
Tell the storage engine that it is allowed to "disable transaction" in the
handler. It is a hint that ACID is not required - it is used in NDB for