List:Internals« Previous MessageNext Message »
From:jani Date:July 22 2005 8:55pm
Subject:bk commit into 5.1 tree (jani:1.1881)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of jani. When jani 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.1881 05/07/22 23:54:59 jani@stripped +23 -0
  Merge jamppa@stripped:/home/bk/mysql-5.1
  into  a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.1

  sql/field.h
    1.167 05/07/22 23:47:34 jani@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.cc
    1.201 05/07/22 23:54:52 jani@stripped +23 -22
    Merge.

  sql/sql_table.cc
    1.260 05/07/22 23:47:38 jani@stripped +0 -0
    Auto merged

  sql/sql_lex.h
    1.191 05/07/22 23:47:37 jani@stripped +0 -0
    Auto merged

  sql/sql_class.h
    1.254 05/07/22 23:47:36 jani@stripped +0 -0
    Auto merged

  sql/set_var.h
    1.69 05/07/22 23:47:36 jani@stripped +0 -0
    Auto merged

  sql/set_var.cc
    1.127 05/07/22 23:47:36 jani@stripped +0 -0
    Auto merged

  sql/mysqld.cc
    1.471 05/07/22 23:47:36 jani@stripped +0 -0
    Auto merged

  sql/mysql_priv.h
    1.323 05/07/22 23:47:36 jani@stripped +0 -0
    Auto merged

  sql/handler.h
    1.152 05/07/22 23:47:35 jani@stripped +0 -0
    Auto merged

  sql/ha_ndbcluster.h
    1.90 05/07/22 23:47:35 jani@stripped +0 -0
    Auto merged

  sql/ha_myisammrg.h
    1.41 05/07/22 23:47:35 jani@stripped +0 -0
    Auto merged

  sql/ha_myisammrg.cc
    1.70 05/07/22 23:47:35 jani@stripped +0 -0
    Auto merged

  sql/ha_myisam.h
    1.69 05/07/22 23:47:35 jani@stripped +0 -0
    Auto merged

  sql/ha_myisam.cc
    1.157 05/07/22 23:47:35 jani@stripped +0 -0
    Auto merged

  sql/ha_innodb.h
    1.100 05/07/22 23:47:35 jani@stripped +0 -0
    Auto merged

  sql/ha_innodb.cc
    1.223 05/07/22 23:47:34 jani@stripped +0 -0
    Auto merged

  sql/ha_heap.h
    1.38 05/07/22 23:47:34 jani@stripped +0 -0
    Auto merged

  sql/ha_heap.cc
    1.72 05/07/22 23:47:34 jani@stripped +0 -0
    Auto merged

  sql/ha_berkeley.h
    1.73 05/07/22 23:47:34 jani@stripped +0 -0
    Auto merged

  sql/ha_berkeley.cc
    1.155 05/07/22 23:47:34 jani@stripped +0 -0
    Auto merged

  sql/field.cc
    1.282 05/07/22 23:47:33 jani@stripped +0 -0
    Auto merged

  BitKeeper/etc/config
    1.17 05/07/22 23:47:33 jani@stripped +0 -1
    Auto merged

# 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:	jani
# Host:	a193-229-222-105.elisa-laajakaista.fi
# Root:	/home/my/bk/mysql-5.1/RESYNC

--- 1.281/sql/field.cc	2005-07-21 01:02:07 +03:00
+++ 1.282/sql/field.cc	2005-07-22 23:47:33 +03:00
@@ -67,6 +67,7 @@
           ((int)FIELDTYPE_TEAR_FROM) + (field_type - FIELDTYPE_TEAR_TO) - 1);
 }
 
+
 static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
 {
   /* MYSQL_TYPE_DECIMAL -> */
@@ -5906,6 +5907,26 @@
 }
 
 
+uint Field::is_equal(create_field *new_field)
+{
+  return (new_field->sql_type == type());
+}
+
+
+uint Field_str::is_equal(create_field *new_field)
+{
+  if (((new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
+       !(flags & (BINCMP_FLAG | BINARY_FLAG))) ||
+      (!(new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
+	(flags & (BINCMP_FLAG | BINARY_FLAG))))
+    return 0; /* One of the fields is binary and the other one isn't */
+
+  return ((new_field->sql_type == type()) &&
+	  new_field->charset == field_charset &&
+	  new_field->length == max_length());
+}
+
+
 int Field_string::store(longlong nr)
 {
   char buff[64];
@@ -6665,6 +6686,22 @@
 }
 
 
+uint Field_varstring::is_equal(create_field *new_field)
+{
+  if (new_field->sql_type == type() &&
+      new_field->charset == field_charset)
+  {
+    if (new_field->length == max_length())
+      return IS_EQUAL_YES;
+    if (new_field->length > max_length() &&
+	((new_field->length <= 255 && max_length() <= 255) ||
+	 (new_field->length > 255 && max_length() > 255)))
+      return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer variable length
+  }
+  return IS_EQUAL_NO;
+}
+
+
 /****************************************************************************
 ** blob type
 ** A blob is saved as a length and a pointer. The length is stored in the
@@ -7771,6 +7808,17 @@
       dec != from_num->dec)
     return 0;
   return 1;
+}
+
+
+uint Field_num::is_equal(create_field *new_field)
+{
+  return ((new_field->sql_type == type()) &&
+	  ((new_field->flags & UNSIGNED_FLAG) == (uint) (flags &
+							 UNSIGNED_FLAG)) &&
+	  ((new_field->flags & AUTO_INCREMENT_FLAG) ==
+	   (uint) (flags & AUTO_INCREMENT_FLAG)) &&
+	  (new_field->length >= max_length()));
 }
 
 

--- 1.166/sql/field.h	2005-07-23 00:05:12 +03:00
+++ 1.167/sql/field.h	2005-07-22 23:47:34 +03:00
@@ -29,6 +29,7 @@
 
 class Send_field;
 class Protocol;
+class create_field;
 struct st_cache_field;
 void field_conv(Field *to,Field *from);
 
@@ -315,6 +316,8 @@
   int warn_if_overflow(int op_result);
   /* maximum possible display length */
   virtual uint32 max_length()= 0;
+
+  virtual uint is_equal(create_field *new_field);
   /* convert decimal to longlong with overflow check */
   longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
                                     int *err);
@@ -355,6 +358,7 @@
   bool eq_def(Field *field);
   int store_decimal(const my_decimal *);
   my_decimal *val_decimal(my_decimal *);
+  uint is_equal(create_field *new_field);
 };
 
 
@@ -379,6 +383,7 @@
   uint32 max_length() { return field_length; }
   friend class create_field;
   my_decimal *val_decimal(my_decimal *);
+  uint is_equal(create_field *new_field);
 };
 
 
@@ -1097,6 +1102,7 @@
   Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
                        char *new_ptr, uchar *new_null_ptr,
                        uint new_null_bit);
+  uint is_equal(create_field *new_field);
 };
 
 

--- 1.154/sql/ha_berkeley.cc	2005-07-21 01:02:07 +03:00
+++ 1.155/sql/ha_berkeley.cc	2005-07-22 23:47:34 +03:00
@@ -2653,4 +2653,14 @@
   return 0;
 }
 
+
+bool ha_berkeley::check_if_incompatible_data(HA_CREATE_INFO *info,
+					     uint table_changes)
+{
+  if (table_changes < IS_EQUAL_YES)
+    return COMPATIBLE_DATA_NO;
+  return COMPATIBLE_DATA_YES;
+}
+
+
 #endif /* HAVE_BERKELEY_DB */

--- 1.72/sql/ha_berkeley.h	2005-07-19 21:43:23 +03:00
+++ 1.73/sql/ha_berkeley.h	2005-07-22 23:47:34 +03:00
@@ -152,6 +152,7 @@
   uint8 table_cache_type() { return HA_CACHE_TBL_TRANSACT; }
   bool primary_key_is_clustered() { return true; }
   int cmp_ref(const byte *ref1, const byte *ref2);
+  bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
 };
 
 extern bool berkeley_shared_data;

--- 1.71/sql/ha_heap.cc	2005-07-20 19:02:25 +03:00
+++ 1.72/sql/ha_heap.cc	2005-07-22 23:47:34 +03:00
@@ -629,3 +629,15 @@
   ha_heap::info(HA_STATUS_AUTO);
   return auto_increment_value;
 }
+
+
+bool ha_heap::check_if_incompatible_data(HA_CREATE_INFO *info,
+					 uint table_changes)
+{
+  /* Check that auto_increment value was not changed */
+  if ((table_changes != IS_EQUAL_YES &&
+       info->used_fields & HA_CREATE_USED_AUTO) &&
+      info->auto_increment_value != 0)
+    return COMPATIBLE_DATA_NO;
+  return COMPATIBLE_DATA_YES;
+}

--- 1.37/sql/ha_heap.h	2005-07-19 21:21:01 +03:00
+++ 1.38/sql/ha_heap.h	2005-07-22 23:47:34 +03:00
@@ -104,6 +104,7 @@
     HEAP_PTR ptr2=*(HEAP_PTR*)ref2;
     return ptr1 < ptr2? -1 : (ptr1 > ptr2? 1 : 0);
   }
+  bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
 private:
   void update_key_stats();
 };

--- 1.156/sql/ha_myisam.cc	2005-07-21 01:02:08 +03:00
+++ 1.157/sql/ha_myisam.cc	2005-07-22 23:47:35 +03:00
@@ -1697,3 +1697,25 @@
   return (uint)file->s->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 != auto_increment_value ||
+      info->raid_type != raid_type ||
+      info->raid_chunks != raid_chunks ||
+      info->raid_chunksize != raid_chunksize ||
+      info->data_file_name != data_file_name ||
+      info->index_file_name != index_file_name ||
+      table_changes == IS_EQUAL_NO)
+    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;
+}

--- 1.68/sql/ha_myisam.h	2005-07-19 21:21:01 +03:00
+++ 1.69/sql/ha_myisam.h	2005-07-22 23:47:35 +03:00
@@ -123,6 +123,7 @@
   int backup(THD* thd, HA_CHECK_OPT* check_opt);
   int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt);
   int preload_keys(THD* thd, HA_CHECK_OPT* check_opt);
+  bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
 #ifdef HAVE_REPLICATION
   int dump(THD* thd, int fd);
   int net_read_dump(NET* net);

--- 1.69/sql/ha_myisammrg.cc	2005-07-21 01:02:08 +03:00
+++ 1.70/sql/ha_myisammrg.cc	2005-07-22 23:47:35 +03:00
@@ -515,3 +515,14 @@
   }
   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;
+}

--- 1.40/sql/ha_myisammrg.h	2005-07-19 21:21:01 +03:00
+++ 1.41/sql/ha_myisammrg.h	2005-07-22 23:47:35 +03:00
@@ -82,4 +82,5 @@
   void update_create_info(HA_CREATE_INFO *create_info);
   void append_create_info(String *packet);
   MYRG_INFO *myrg_info() { return file; }
+  bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
 };

--- 1.151/sql/handler.h	2005-07-22 21:46:55 +03:00
+++ 1.152/sql/handler.h	2005-07-22 23:47:35 +03:00
@@ -226,6 +226,9 @@
 #define MAXGTRIDSIZE 64
 #define MAXBQUALSIZE 64
 
+#define COMPATIBLE_DATA_YES 0
+#define COMPATIBLE_DATA_NO  1
+
 struct xid_t {
   long formatID;
   long gtrid_length;
@@ -1258,6 +1261,9 @@
      Pops the top if condition stack, if stack is not empty
  */
  virtual void cond_pop() { return; };
+ virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
+					 uint table_changes)
+ { return COMPATIBLE_DATA_NO; }
 };
 
 	/* Some extern variables used with handlers */

--- 1.322/sql/mysql_priv.h	2005-07-21 11:50:17 +03:00
+++ 1.323/sql/mysql_priv.h	2005-07-22 23:47:36 +03:00
@@ -392,6 +392,13 @@
 
 #define STRING_BUFFER_USUAL_SIZE 80
 
+/*
+  Some defines for exit codes for ::is_equal class functions.
+*/
+#define IS_EQUAL_NO 0
+#define IS_EQUAL_YES 1
+#define IS_EQUAL_PACK_LENGTH 2
+
 enum enum_parsing_place
 {
   NO_MATTER,

--- 1.470/sql/mysqld.cc	2005-07-20 08:53:07 +03:00
+++ 1.471/sql/mysqld.cc	2005-07-22 23:47:36 +03:00
@@ -4341,6 +4341,7 @@
   OPT_ENABLE_SHARED_MEMORY,
   OPT_SHARED_MEMORY_BASE_NAME,
   OPT_OLD_PASSWORDS,
+  OPT_OLD_ALTER_TABLE,
   OPT_EXPIRE_LOGS_DAYS,
   OPT_GROUP_CONCAT_MAX_LEN,
   OPT_DEFAULT_COLLATION,
@@ -4877,6 +4878,11 @@
    (gptr*) &opt_no_mix_types, (gptr*) &opt_no_mix_types, 0, GET_BOOL, NO_ARG,
    0, 0, 0, 0, 0, 0},
 #endif
+  {"old-alter-table", OPT_OLD_ALTER_TABLE,
+   "Use old, non-optimized alter table.",
+   (gptr*) &global_system_variables.old_alter_table,
+   (gptr*) &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
+   0, 0, 0, 0, 0, 0},
   {"old-passwords", OPT_OLD_PASSWORDS, "Use old password encryption method (needed for 4.0 and older clients).",
    (gptr*) &global_system_variables.old_passwords,
    (gptr*) &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG,
@@ -6069,6 +6075,7 @@
   global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
   max_system_variables.max_join_size=   (ulonglong) HA_POS_ERROR;
   global_system_variables.old_passwords= 0;
+  global_system_variables.old_alter_table= 0;
 
   /* Variables that depends on compile options */
 #ifndef DBUG_OFF

--- 1.253/sql/sql_class.h	2005-07-19 21:43:25 +03:00
+++ 1.254/sql/sql_class.h	2005-07-22 23:47:36 +03:00
@@ -564,6 +564,7 @@
   my_bool ndb_use_exact_count;
   my_bool ndb_use_transactions;
 #endif /* HAVE_NDBCLUSTER_DB */
+  my_bool old_alter_table;
   my_bool old_passwords;
   
   /* Only charset part of these variables is sensible */

--- 1.190/sql/sql_lex.h	2005-07-19 21:43:25 +03:00
+++ 1.191/sql/sql_lex.h	2005-07-22 23:47:37 +03:00
@@ -649,6 +649,7 @@
 #define ALTER_KEYS_ONOFF        512
 #define ALTER_CONVERT          1024
 #define ALTER_FORCE		2048
+#define ALTER_RECREATE          4096
 
 typedef struct st_alter_info
 {

--- 1.259/sql/sql_table.cc	2005-07-21 11:50:17 +03:00
+++ 1.260/sql/sql_table.cc	2005-07-22 23:47:38 +03:00
@@ -1348,6 +1348,34 @@
 
 
 /*
+  Set table default charset, if not set
+
+  SYNOPSIS
+    set_table_default_charset()
+    create_info        Table create information
+
+  DESCRIPTION
+    If the table character set was not given explicitely,
+    let's fetch the database default character set and
+    apply it to the table.
+*/
+
+static void set_table_default_charset(THD *thd,
+				      HA_CREATE_INFO *create_info, char *db)
+{
+  if (!create_info->default_table_charset)
+  {
+    HA_CREATE_INFO db_info;
+    char path[FN_REFLEN];
+    /* Abuse build_table_path() to build the path to the db.opt file */
+    build_table_path(path, sizeof(path), db, MY_DB_OPT_FILE, "");
+    load_db_opt(thd, path, &db_info);
+    create_info->default_table_charset= db_info.default_table_charset;
+  }
+}
+
+
+/*
   Extend long VARCHAR fields to blob & prepare field if it's a blob
 
   SYNOPSIS
@@ -1581,20 +1609,7 @@
   }
 #endif
 
-  /*
-    If the table character set was not given explicitely,
-    let's fetch the database default character set and
-    apply it to the table.
-  */
-  if (!create_info->default_table_charset)
-  {
-    HA_CREATE_INFO db_info;
-    char  path[FN_REFLEN];
-    /* Abuse build_table_path() to build the path to the db.opt file */
-    build_table_path(path, sizeof(path), db, MY_DB_OPT_FILE, "");
-    load_db_opt(thd, path, &db_info);
-    create_info->default_table_charset= db_info.default_table_charset;
-  }
+  set_table_default_charset(thd, create_info, (char*) db);
 
   if (mysql_prepare_table(thd, create_info, &fields,
 			  &keys, internal_tmp_table, &db_options, file,
@@ -3090,6 +3105,166 @@
 #endif /* NOT_USED */
 
 
+
+#define ALTER_TABLE_DATA_CHANGED  1
+#define ALTER_TABLE_INDEX_CHANGED 2
+
+/*
+  SYNOPSIS
+    compare tables()
+    table       original table
+    create_list fields in new table
+    key_list    keys in new table
+    create_info create options in new table
+
+  DESCRIPTION
+    'table' (first argument) contains information of the original
+    table, which includes all corresponding parts that the new
+    table has in arguments create_list, key_list and create_info.
+
+    By comparing the changes between the original and new table
+    we can determine how much it has changed after ALTER TABLE
+    and whether we need to make a copy of the table, or just change
+    the .frm file.
+
+  RETURN VALUES
+    0 No copy needed
+    1 Data changes, copy needed
+    2 Index changes, copy needed   
+*/
+
+uint compare_tables(TABLE *table, List<create_field> *create_list,
+		    List<Key> *key_list, HA_CREATE_INFO *create_info,
+		    ALTER_INFO *alter_info, uint order_num)
+{
+  Field **f_ptr, *field;
+  uint changes= 0, tmp;
+  List_iterator_fast<create_field> new_field_it(*create_list);
+  create_field *new_field;
+
+  /*
+    Some very basic checks. If number of fields changes, or the
+    handler, we need to run full ALTER TABLE. In the future
+    new fields can be added and old dropped without copy, but
+    not yet.
+
+    Test also that engine was not given during ALTER TABLE, or
+    we are force to run regular alter table (copy).
+    E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
+
+    For the following ones we also want to run regular alter table:
+    ALTER TABLE tbl_name ORDER BY ..
+    ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
+
+    At the moment we can't handle altering temporary tables without a copy.
+    We also test if OPTIMIZE TABLE was given and was mapped to alter table.
+    In that case we always do full copy.
+  */
+  if (table->s->fields != create_list->elements ||
+      table->s->db_type != create_info->db_type ||
+      table->s->tmp_table ||
+      create_info->used_fields & HA_CREATE_USED_ENGINE ||
+      create_info->used_fields & HA_CREATE_USED_CHARSET ||
+      create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
+      (alter_info->flags & ALTER_RECREATE) ||
+      order_num)
+    return ALTER_TABLE_DATA_CHANGED;
+
+  /*
+    Go through fields and check if the original ones are compatible
+    with new table.
+  */
+  for (f_ptr= table->field, new_field= new_field_it++;
+       (field= *f_ptr); f_ptr++, new_field= new_field_it++)
+  {
+    /* Make sure we have at least the default charset in use. */
+    if (!new_field->charset)
+      new_field->charset= create_info->default_table_charset;
+    
+    /* Check that NULL behavior is same for old and new fields */
+    if ((new_field->flags & NOT_NULL_FLAG) !=
+	(uint) (field->flags & NOT_NULL_FLAG))
+      return ALTER_TABLE_DATA_CHANGED;
+
+    /* Don't pack rows in old tables if the user has requested this. */
+    if (create_info->row_type == ROW_TYPE_DYNAMIC ||
+	(new_field->flags & BLOB_FLAG) ||
+	new_field->sql_type == MYSQL_TYPE_VARCHAR &&
+	create_info->row_type != ROW_TYPE_FIXED)
+      create_info->table_options|= HA_OPTION_PACK_RECORD;
+
+    /* Evaluate changes bitmap and send to check_if_incompatible_data() */
+    if (!(tmp= field->is_equal(new_field)))
+      return ALTER_TABLE_DATA_CHANGED;
+
+    changes|= tmp;
+  }
+  /* Check if changes are compatible with current handler without a copy */
+  if (table->file->check_if_incompatible_data(create_info, changes))
+    return ALTER_TABLE_DATA_CHANGED;
+
+  /*
+    Go through keys and check if the original ones are compatible
+    with new table.
+  */
+  KEY *table_key_info= table->key_info;
+  List_iterator_fast<Key> key_it(*key_list);
+  Key *key= key_it++;
+
+  /* Check if the number of key elements has changed */
+  if  (table->s->keys != key_list->elements)
+    return ALTER_TABLE_INDEX_CHANGED;
+
+  for (uint i= 0; i < table->s->keys; i++, table_key_info++, key= key_it++)
+  {
+    /*
+      Check that the key types are compatible between old and new tables.
+    */
+    if (table_key_info->algorithm != key->algorithm ||
+	((key->type == Key::PRIMARY || key->type == Key::UNIQUE) &&
+	 !(table_key_info->flags & HA_NOSAME)) ||
+	(!(key->type == Key::PRIMARY || key->type == Key::UNIQUE) &&
+	 (table_key_info->flags & HA_NOSAME)) ||
+	((key->type == Key::SPATIAL) &&
+	 !(table_key_info->flags & HA_SPATIAL)) ||
+	(!(key->type == Key::SPATIAL) &&
+	 (table_key_info->flags & HA_SPATIAL)) ||
+	((key->type == Key::FULLTEXT) &&
+	 !(table_key_info->flags & HA_FULLTEXT)) ||
+	(!(key->type == Key::FULLTEXT) &&
+	 (table_key_info->flags & HA_FULLTEXT)))
+      return ALTER_TABLE_INDEX_CHANGED;
+    
+    if  (table_key_info->key_parts != key->columns.elements)
+      return ALTER_TABLE_INDEX_CHANGED;
+
+    /*
+      Check that the key parts remain compatible between the old and
+      new tables.
+    */
+    KEY_PART_INFO *table_key_part= table_key_info->key_part;
+    List_iterator_fast<key_part_spec> key_part_it(key->columns);
+    key_part_spec *key_part= key_part_it++;
+    for (uint j= 0; j < table_key_info->key_parts; j++,
+	   table_key_part++, key_part= key_part_it++)
+    {
+      /*
+	Key definition has changed if we are using a different field or
+	if the used key length is different
+	(If key_part->length == 0 it means we are using the whole field)
+      */
+      if (strcmp(key_part->field_name, table_key_part->field->field_name) ||
+	  (key_part->length && key_part->length != table_key_part->length) ||
+	  (key_part->length == 0 && table_key_part->length !=
+	   table_key_part->field->pack_length()))
+	return ALTER_TABLE_INDEX_CHANGED;	
+    }
+  }
+
+  return 0; // Tables are compatible
+}
+
+
 /*
   Alter table
 */
@@ -3111,7 +3286,7 @@
   ulonglong next_insert_id;
   uint db_create_options, used_fields;
   enum db_type old_db_type,new_db_type;
-  bool need_copy_table;
+  uint need_copy_table= 0;
   DBUG_ENTER("mysql_alter_table");
 
   thd->proc_info="init";
@@ -3389,8 +3564,8 @@
 	def_it.remove();
       }
     }
-    else
-    {						// Use old field value
+    else // This field was not dropped and not changed, add it to the list
+    {	 // for the new table.   
       create_list.push_back(def=new create_field(field,field));
       alter_it.rewind();			// Change default if ALTER
       Alter_column *alter;
@@ -3603,17 +3778,22 @@
   if (table->s->tmp_table)
     create_info->options|=HA_LEX_CREATE_TMP_TABLE;
 
+  set_table_default_charset(thd, create_info, db);
+
+  if (thd->variables.old_alter_table)
+    need_copy_table= 1;
+  else
+    need_copy_table= compare_tables(table, &create_list, &key_list,
+				    create_info, alter_info, order_num);
+
   /*
     better have a negative test here, instead of positive, like
     alter_info->flags & ALTER_ADD_COLUMN|ALTER_ADD_INDEX|...
     so that ALTER TABLE won't break when somebody will add new flag
   */
-  need_copy_table= (alter_info->flags &
-                    ~(ALTER_CHANGE_COLUMN_DEFAULT|ALTER_OPTIONS) ||
-                    (create_info->used_fields &
-                     ~(HA_CREATE_USED_COMMENT|HA_CREATE_USED_PASSWORD)) ||
-                    table->s->tmp_table);
-  create_info->frm_only= !need_copy_table;
+
+  if (!need_copy_table)
+    create_info->frm_only= 1;
 
   /*
     Handling of symlinked tables:
@@ -3920,7 +4100,7 @@
  err:
   DBUG_RETURN(TRUE);
 }
-
+/* mysql_alter_table */
 
 static int
 copy_data_between_tables(TABLE *from,TABLE *to,
@@ -4132,7 +4312,7 @@
   create_info.row_type=ROW_TYPE_NOT_USED;
   create_info.default_table_charset=default_charset_info;
   /* Force alter table to recreate table */
-  lex->alter_info.flags= ALTER_CHANGE_COLUMN;
+  lex->alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
   DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
                                 table_list, lex->create_list,
                                 lex->key_list, 0, (ORDER *) 0,

--- 1.16/BitKeeper/etc/config	2005-07-19 21:43:22 +03:00
+++ 1.17/BitKeeper/etc/config	2005-07-22 23:47:33 +03:00
@@ -73,3 +73,8 @@
 [nick:]checkout:get
 checkout:edit
 eoln:unix
+
+license:
+licsign1:
+licsign2:
+licsign3:

--- 1.200/sql/ha_ndbcluster.cc	2005-07-21 13:50:20 +03:00
+++ 1.201/sql/ha_ndbcluster.cc	2005-07-22 23:54:52 +03:00
@@ -7498,4 +7498,27 @@
   tab.setNodeGroupIds(&node_group, no_fragments);
   DBUG_VOID_RETURN;
 }
+
+
+bool ha_ndbcluster::check_if_incompatible_data(HA_CREATE_INFO *info,
+					       uint table_changes)
+{
+  return COMPATIBLE_DATA_NO;
+
+  if (table_changes != IS_EQUAL_YES)
+    return COMPATIBLE_DATA_NO;
+  
+  /* Check that auto_increment value was not changed */
+  if ((info->used_fields & HA_CREATE_USED_AUTO) &&
+      info->auto_increment_value != 0)
+    return COMPATIBLE_DATA_NO;
+  
+  /* Check that row format didn't change */
+  if ((info->used_fields & HA_CREATE_USED_AUTO) &&
+      get_row_type() != info->row_type)
+    return COMPATIBLE_DATA_NO;
+
+  return COMPATIBLE_DATA_YES;
+}
+
 #endif /* HAVE_NDBCLUSTER_DB */

--- 1.89/sql/ha_ndbcluster.h	2005-07-18 14:30:11 +03:00
+++ 1.90/sql/ha_ndbcluster.h	2005-07-22 23:47:35 +03:00
@@ -540,6 +540,10 @@
                                      uint key_length,
                                      qc_engine_callback *engine_callback,
                                      ulonglong *engine_data);
+
+  bool ha_ndbcluster::check_if_incompatible_data(HA_CREATE_INFO *info,
+						 uint table_changes);
+
 private:
   int alter_table_name(const char *to);
   int drop_table();

--- 1.222/sql/ha_innodb.cc	2005-07-21 01:02:08 +03:00
+++ 1.223/sql/ha_innodb.cc	2005-07-22 23:47:34 +03:00
@@ -7132,4 +7132,24 @@
 	}
 }
 
+
+bool ha_innobase::check_if_incompatible_data(HA_CREATE_INFO *info,
+					     uint table_changes)
+{
+  if (table_changes != IS_EQUAL_YES)
+    return COMPATIBLE_DATA_NO;
+  
+  /* Check that auto_increment value was not changed */
+  if ((info->used_fields & HA_CREATE_USED_AUTO) &&
+      info->auto_increment_value != 0)
+    return COMPATIBLE_DATA_NO;
+  
+  /* Check that row format didn't change */
+  if ((info->used_fields & HA_CREATE_USED_AUTO) &&
+      get_row_type() != info->row_type)
+    return COMPATIBLE_DATA_NO;
+
+  return COMPATIBLE_DATA_YES;
+}
+
 #endif /* HAVE_INNOBASE_DB */

--- 1.99/sql/ha_innodb.h	2005-07-19 21:43:23 +03:00
+++ 1.100/sql/ha_innodb.h	2005-07-22 23:47:35 +03:00
@@ -202,6 +202,8 @@
         static ulonglong get_mysql_bin_log_pos();
         bool primary_key_is_clustered() { return true; }
         int cmp_ref(const byte *ref1, const byte *ref2);
+	bool ha_innobase::check_if_incompatible_data(HA_CREATE_INFO *info,
+						     uint table_changes);
 };
 
 extern struct show_var_st innodb_status_variables[];

--- 1.126/sql/set_var.cc	2005-07-19 21:43:25 +03:00
+++ 1.127/sql/set_var.cc	2005-07-22 23:47:36 +03:00
@@ -284,6 +284,8 @@
 					    &SV::net_retry_count,
 					    0, fix_net_retry_count);
 sys_var_thd_bool	sys_new_mode("new", &SV::new_mode);
+sys_var_thd_bool	sys_old_alter_table("old_alter_table",
+					    &SV::old_alter_table);
 sys_var_thd_bool	sys_old_passwords("old_passwords", &SV::old_passwords);
 sys_var_thd_ulong       sys_optimizer_prune_level("optimizer_prune_level",
                                                   &SV::optimizer_prune_level);
@@ -632,6 +634,7 @@
   &sys_net_wait_timeout,
   &sys_net_write_timeout,
   &sys_new_mode,
+  &sys_old_alter_table,
   &sys_old_passwords,
   &sys_optimizer_prune_level,
   &sys_optimizer_search_depth,
@@ -907,6 +910,7 @@
   {sys_net_retry_count.name,  (char*) &sys_net_retry_count,	    SHOW_SYS},
   {sys_net_write_timeout.name,(char*) &sys_net_write_timeout,       SHOW_SYS},
   {sys_new_mode.name,         (char*) &sys_new_mode,                SHOW_SYS},
+  {sys_old_alter_table.name,  (char*) &sys_old_alter_table,         SHOW_SYS},
   {sys_old_passwords.name,    (char*) &sys_old_passwords,           SHOW_SYS},
   {"open_files_limit",	      (char*) &open_files_limit,	    SHOW_LONG},
   {sys_optimizer_prune_level.name, (char*) &sys_optimizer_prune_level,

--- 1.68/sql/set_var.h	2005-07-16 12:45:23 +03:00
+++ 1.69/sql/set_var.h	2005-07-22 23:47:36 +03:00
@@ -877,6 +877,7 @@
 
 /* updated in sql_acl.cc */
 
+extern sys_var_thd_bool sys_old_alter_table;
 extern sys_var_thd_bool sys_old_passwords;
 extern LEX_STRING default_key_cache_base;
 
Thread
bk commit into 5.1 tree (jani:1.1881)jani22 Jul