summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <jimw@mysql.com>2005-06-09 19:29:55 -0700
committerunknown <jimw@mysql.com>2005-06-09 19:29:55 -0700
commit5b81b2dc87261d55b8f18bc89c24a426c35c5603 (patch)
tree7b9f0710e776850ddf034f4f8038ccf75689465e /sql
parenta3fe14096397ddd8ce7095aad9361c25090569ca (diff)
parentdd8e174fa6a07ebf21a3b0a03883d2be694b827b (diff)
downloadmariadb-git-5b81b2dc87261d55b8f18bc89c24a426c35c5603.tar.gz
Merge mysql.com:/home/jimw/my/mysql-5.0-10543
into mysql.com:/home/jimw/my/mysql-5.0-clean sql/field.cc: Auto merged sql/field.h: Auto merged sql/sql_table.cc: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc33
-rw-r--r--sql/field.h1
-rw-r--r--sql/sql_table.cc25
3 files changed, 53 insertions, 6 deletions
diff --git a/sql/field.cc b/sql/field.cc
index a50190543b5..89ef25475ff 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -982,6 +982,39 @@ Item_result Field::result_merge_type(enum_field_types field_type)
Static help functions
*****************************************************************************/
+
+/*
+ Check whether a field type can be partially indexed by a key
+
+ This is a static method, rather than a virtual function, because we need
+ to check the type of a non-Field in mysql_alter_table().
+
+ SYNOPSIS
+ type_can_have_key_part()
+ type field type
+
+ RETURN
+ TRUE Type can have a prefixed key
+ FALSE Type can not have a prefixed key
+*/
+
+bool Field::type_can_have_key_part(enum enum_field_types type)
+{
+ switch (type) {
+ case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_TINY_BLOB:
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ case MYSQL_TYPE_LONG_BLOB:
+ case MYSQL_TYPE_BLOB:
+ case MYSQL_TYPE_VAR_STRING:
+ case MYSQL_TYPE_STRING:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+
/*
Numeric fields base class constructor
*/
diff --git a/sql/field.h b/sql/field.h
index d58746b6068..a522558a8d7 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -119,6 +119,7 @@ public:
virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); }
virtual Item_result cast_to_int_type () const { return result_type(); }
+ static bool type_can_have_key_part(enum_field_types);
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
static Item_result result_merge_type(enum_field_types);
bool eq(Field *field)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2cf9386d0e4..8a29c481dc1 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3398,12 +3398,25 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
continue; // Field is removed
uint key_part_length=key_part->length;
if (cfield->field) // Not new field
- { // Check if sub key
- if (cfield->field->type() != FIELD_TYPE_BLOB &&
- (cfield->field->pack_length() == key_part_length ||
- cfield->length <= key_part_length /
- key_part->field->charset()->mbmaxlen))
- key_part_length=0; // Use whole field
+ {
+ /*
+ If the field can't have only a part used in a key according to its
+ new type, or should not be used partially according to its
+ previous type, or the field length is less than the key part
+ length, unset the key part length.
+
+ We also unset the key part length if it is the same as the
+ old field's length, so the whole new field will be used.
+
+ BLOBs may have cfield->length == 0, which is why we test it before
+ checking whether cfield->length < key_part_length (in chars).
+ */
+ if (!Field::type_can_have_key_part(cfield->field->type()) ||
+ !Field::type_can_have_key_part(cfield->sql_type) ||
+ cfield->field->field_length == key_part_length ||
+ (cfield->length && (cfield->length < key_part_length /
+ key_part->field->charset()->mbmaxlen)))
+ key_part_length= 0; // Use whole field
}
key_part_length /= key_part->field->charset()->mbmaxlen;
key_parts.push_back(new key_part_spec(cfield->field_name,