Commit f1e25513 authored by unknown's avatar unknown
Browse files

Faster alter table code for 5.1.


mysql-test/r/alter_table.result:
  Added some additional tests for new alter table code.
mysql-test/t/alter_table.test:
  Added some additional tests for new alter table code.
sql/field.cc:
  Functions to check whether new field is equal with old field.
  Classes for different types.
sql/field.h:
  Functions to check whether new field is equal with old field.
  Classes for different types.
sql/ha_berkeley.cc:
  check_if_incompatible_data() for BDB.
sql/ha_berkeley.h:
  check_if_incompatible_data() for BDB.
sql/ha_heap.cc:
  check_if_incompatible_data() for HEAP.
sql/ha_heap.h:
  check_if_incompatible_data() for HEAP.
sql/ha_innodb.cc:
  check_if_incompatible_data() for InnoDB.
sql/ha_innodb.h:
  check_if_incompatible_data() for InnoBD.
sql/ha_myisam.cc:
  check_if_incompatible_data() for MyISAM.
sql/ha_myisam.h:
  check_if_incompatible_data() for MyISAM.
sql/ha_myisammrg.cc:
  check_if_incompatible_data() for Merge tables.
sql/ha_myisammrg.h:
  check_if_incompatible_data() for Merge tables.
sql/ha_ndbcluster.cc:
  check_if_incompatible_data() for NDB.
sql/ha_ndbcluster.h:
  check_if_incompatible_data() for NDB.
sql/handler.h:
  Defines for COMPATIBLE_DATA (yes and no) and the default function
  for check_if_incompatible_data().
sql/mysql_priv.h:
  Defines for IS_EQUAL_*
sql/mysqld.cc:
  Added option --old-alter-table to disable new alter table code.
sql/set_var.cc:
  Added option --old-alter-table to disable new alter table code.
sql/set_var.h:
  Added option --old-alter-table to disable new alter table code.
sql/sql_class.h:
  Added option --old-alter-table to disable new alter table code.
sql/sql_lex.h:
  Added a flag for forcing recreation of a table
  (needed for optimize table mapped to alter table)
sql/sql_table.cc:
  Made a function of setting table default charset, used
  now in two places.
  
  Added defines for ALTER_TABLE_* possible changes.
  Currently just overall data and index.
  
  Added function compare_tables, which checks fields
  compatibility in old and new tables.
BitKeeper/etc/config:
  Disabled logging
parent 501f7307
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ description: MySQL - fast and reliable SQL database
# repository is commercial it can be an internal email address or "none"
# to disable logging.
# 
logging:  logging@openlogging.org
logging:  none
# 
# If this field is set, all checkins will appear to be made by this user,
# in effect making this a single user package.  Single user packages are
@@ -73,3 +73,8 @@ hours:
[nick:]checkout:get
checkout:edit
eoln:unix

license: BKL5433d4e6925a06a150001200fff9b
licsign1: YgAAAo0AAAADgAAAAEYUtZil1XCmH6z+LTlQMDJ+1ZeBLIgtHo1azUxQ8/8G1JuW
licsign2: fxW3y9raSlpYVAleJSaBDKYiVtEuSdaUN2ILLo6Wc8TJmLl0aprUy7Lh/m/Sq/YC
licsign3: 0H7qah3bdItuw7NGNSLfBzigbKOF6kPbU84VlAUhOqLR2e5Zf32SBZhtCYGA
+54 −0
Original line number Diff line number Diff line
@@ -537,3 +537,57 @@ create table t1 ( a timestamp );
alter table t1 add unique ( a(1) );
ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys
drop table t1;
create table t1 (v varchar(32));
insert into t1 values ('def'),('abc'),('hij'),('3r4f');
select * from t1;
v
def
abc
hij
3r4f
alter table t1 change v v2 varchar(32);
select * from t1;
v2
def
abc
hij
3r4f
alter table t1 change v2 v varchar(64);
select * from t1;
v
def
abc
hij
3r4f
update t1 set v = 'lmn' where v = 'hij';
select * from t1;
v
def
abc
lmn
3r4f
alter table t1 add i int auto_increment not null primary key first;
select * from t1;
i	v
1	def
2	abc
3	lmn
4	3r4f
update t1 set i=5 where i=3;
select * from t1;
i	v
1	def
2	abc
5	lmn
4	3r4f
alter table t1 change i i bigint;
select * from t1;
i	v
1	def
2	abc
5	lmn
4	3r4f
alter table t1 add unique key (i, v);
select * from t1 where i between 2 and 4 and v in ('def','3r4f','lmn');
i	v
4	3r4f
+27 −0
Original line number Diff line number Diff line
@@ -360,3 +360,30 @@ create table t1 ( a timestamp );
--error 1089
alter table t1 add unique ( a(1) );
drop table t1;

#
# Some additional tests for new, faster alter table.
# Note that most of the whole alter table code is being
# tested all around the test suite already.
#

create table t1 (v varchar(32));
insert into t1 values ('def'),('abc'),('hij'),('3r4f');
select * from t1;
# Fast alter, no copy performed
alter table t1 change v v2 varchar(32);
select * from t1;
# Fast alter, no copy performed
alter table t1 change v2 v varchar(64);
select * from t1;
update t1 set v = 'lmn' where v = 'hij';
select * from t1;
# Regular alter table
alter table t1 add i int auto_increment not null primary key first;
select * from t1;
update t1 set i=5 where i=3;
select * from t1;
alter table t1 change i i bigint;
select * from t1;
alter table t1 add unique key (i, v);
select * from t1 where i between 2 and 4 and v in ('def','3r4f','lmn');
+48 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ inline int field_type2index (enum_field_types field_type)
          ((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 -> */
@@ -5920,6 +5921,26 @@ int Field_str::store(double nr)
}


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];
@@ -6676,6 +6697,22 @@ Field *Field_varstring::new_key_field(MEM_ROOT *root,
}


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
@@ -7777,6 +7814,17 @@ bool Field_num::eq_def(Field *field)
}


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()));
}


/*
  Bit field.

+6 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

class Send_field;
class Protocol;
class create_field;
struct st_cache_field;
void field_conv(Field *to,Field *from);

@@ -305,6 +306,8 @@ class Field
  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);
@@ -345,6 +348,7 @@ class Field_num :public Field {
  bool eq_def(Field *field);
  int store_decimal(const my_decimal *);
  my_decimal *val_decimal(my_decimal *);
  uint is_equal(create_field *new_field);
};


@@ -369,6 +373,7 @@ class Field_str :public Field {
  uint32 max_length() { return field_length; }
  friend class create_field;
  my_decimal *val_decimal(my_decimal *);
  uint is_equal(create_field *new_field);
};


@@ -1082,6 +1087,7 @@ class Field_varstring :public Field_longstr {
  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);
};


Loading