1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

MDEV-33658 1/2 Refactoring: extract Key length initialization

mysql_prepare_create_table: Extract a Key initialization part that
relates to length calculation and long unique index designation.

append_system_key_parts call also moves there.

Move this initialization before the duplicate elimination.

Extract WITHOUT OVERPLAPS check into a separate function. It had to be moved
earlier in the code to preserve the order of the error checks, as in the tests.
This commit is contained in:
Nikita Malyavin
2024-10-12 21:32:18 +02:00
parent e33064e0fc
commit ecaedbe299
10 changed files with 362 additions and 251 deletions

View File

@@ -3558,6 +3558,303 @@ key_add_part_check_null(const handler *file, KEY *key_info,
}
static
my_bool key_check_without_overlaps(THD *thd, HA_CREATE_INFO *create_info,
Alter_info *alter_info,
Key &key)
{
DBUG_ENTER("key_check_without_overlaps");
if (!key.without_overlaps)
DBUG_RETURN(FALSE);
// append_system_key_parts is already called, so we should check all the
// columns except the last two.
const auto &period_start= create_info->period_info.period.start;
const auto &period_end= create_info->period_info.period.end;
List_iterator<Key_part_spec> part_it_forwarded(key.columns);
List_iterator<Key_part_spec> part_it(key.columns);
part_it_forwarded++;
part_it_forwarded++;
while (part_it_forwarded++)
{
Key_part_spec *key_part= part_it++;
if (period_start.streq(key_part->field_name)
|| period_end.streq(key_part->field_name))
{
my_error(ER_KEY_CONTAINS_PERIOD_FIELDS, MYF(0), key.name.str,
key_part->field_name.str);
DBUG_RETURN(TRUE);
}
}
if (key.key_create_info.algorithm == HA_KEY_ALG_HASH ||
key.key_create_info.algorithm == HA_KEY_ALG_LONG_HASH)
{
my_error(ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS, MYF(0), key.name.str);
DBUG_RETURN(TRUE);
}
for (Key &key2: alter_info->key_list)
{
if (key2.type != Key::FOREIGN_KEY)
continue;
DBUG_ASSERT(&key != &key2);
const Foreign_key &fk= (Foreign_key&)key2;
if (fk.update_opt != FK_OPTION_CASCADE)
continue;
for (Key_part_spec& kp: key.columns)
{
for (Key_part_spec& kp2: fk.columns)
{
if (kp.field_name.streq(kp2.field_name))
{
my_error(ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS, MYF(0), key.name.str);
DBUG_RETURN(TRUE);
}
}
}
}
create_info->period_info.unique_keys++;
DBUG_RETURN(FALSE);
}
static
my_bool init_key_part_spec(THD *thd, Alter_info *alter_info,
const handler *file,
const Key &key, Key_part_spec &kp,
uint max_key_length, uint max_key_part_length,
bool *is_hash_field_needed)
{
DBUG_ENTER("init_key_part_spec");
const Lex_ident &field_name= kp.field_name;
Create_field *column= NULL;
for (Create_field &c: alter_info->create_list)
if (c.field_name.streq(field_name))
column= &c;
/*
Either field is not present or field visibility is > INVISIBLE_USER
*/
if (!column || (column->invisible > INVISIBLE_USER && !kp.generated))
{
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), field_name.str);
DBUG_RETURN(TRUE);
}
if (DBUG_EVALUATE_IF("test_invisible_index", 0, 1)
&& column->invisible > INVISIBLE_USER
&& !(column->flags & VERS_SYSTEM_FIELD) && !key.invisible)
{
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
const Type_handler *type_handler= column->type_handler();
switch(key.type)
{
case Key::FULLTEXT:
if (type_handler->Key_part_spec_init_ft(&kp, *column))
{
my_error(ER_BAD_FT_COLUMN, MYF(0), field_name.str);
DBUG_RETURN(-1);
}
break;
case Key::SPATIAL:
if (type_handler->Key_part_spec_init_spatial(&kp, *column))
DBUG_RETURN(TRUE);
break;
case Key::PRIMARY:
if (column->vcol_info)
{
my_error(ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN, MYF(0));
DBUG_RETURN(TRUE);
}
if (type_handler->Key_part_spec_init_primary(&kp, *column, file))
DBUG_RETURN(TRUE);
break;
case Key::MULTIPLE:
if (type_handler->Key_part_spec_init_multiple(&kp, *column, file))
DBUG_RETURN(TRUE);
break;
case Key::FOREIGN_KEY:
if (type_handler->Key_part_spec_init_foreign(&kp, *column, file))
DBUG_RETURN(TRUE);
break;
case Key::UNIQUE:
if (type_handler->Key_part_spec_init_unique(&kp, *column, file,
is_hash_field_needed))
DBUG_RETURN(TRUE);
break;
}
uint key_part_length= type_handler->calc_key_length(*column);
if (kp.length)
{
if (f_is_blob(column->pack_flag))
{
key_part_length= MY_MIN(kp.length,
blob_length_by_type(column->real_field_type())
* column->charset->mbmaxlen);
if (key_part_length > max_key_length ||
key_part_length > max_key_part_length)
{
if (key.type == Key::MULTIPLE)
{
key_part_length= MY_MIN(max_key_length, max_key_part_length);
/* not a critical problem */
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY),
key_part_length);
/* Align key length to multibyte char boundary */
key_part_length-= key_part_length % column->charset->mbmaxlen;
}
}
}
// Catch invalid use of partial keys
else if (!f_is_geom(column->pack_flag) &&
// is the key partial?
kp.length != key_part_length &&
// is prefix length bigger than field length?
(kp.length > key_part_length ||
// can the field have a partial key?
!type_handler->type_can_have_key_part() ||
// a packed field can't be used in a partial key
f_is_packed(column->pack_flag) ||
// does the storage engine allow prefixed search?
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
// and is this a 'unique' key?
(key.type == Key::PRIMARY || key.type == Key::UNIQUE))))
{
my_message(ER_WRONG_SUB_KEY, ER_THD(thd, ER_WRONG_SUB_KEY), MYF(0));
DBUG_RETURN(TRUE);
}
else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
key_part_length= kp.length;
}
else if (key_part_length == 0 && (column->flags & NOT_NULL_FLAG) &&
!*is_hash_field_needed)
{
my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), field_name.str);
DBUG_RETURN(TRUE);
}
if (key_part_length > max_key_part_length && key.type != Key::FULLTEXT)
{
if (key.type == Key::MULTIPLE)
{
key_part_length= max_key_part_length;
/* not a critical problem */
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY),
key_part_length);
/* Align key length to multibyte char boundary */
key_part_length-= key_part_length % column->charset->mbmaxlen;
}
else if (key.type != Key::UNIQUE)
{
key_part_length= MY_MIN(max_key_length, max_key_part_length);
my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
DBUG_RETURN(TRUE);
}
}
if (key.type == Key::UNIQUE && key_part_length > MY_MIN(max_key_length,
max_key_part_length))
*is_hash_field_needed= true;
/* We can not store key_part_length more than 2^16 - 1 in frm. */
if (*is_hash_field_needed && kp.length > UINT_MAX16)
{
my_error(ER_TOO_LONG_KEYPART, MYF(0), UINT_MAX16);
DBUG_RETURN(TRUE);
}
kp.length= key_part_length;
DBUG_RETURN(FALSE);
}
/**
@brief Initialize the key length and algorithm (if long hash).
This function does:
1. Append system key parts (versioning, periods)
2. Call Type_handler key_part initialization function.
3. Determine the length of each key_part.
4. Calculate the total Key length.
5. Determine if the key is long unique based on its length
smd result from type handler. It'll be saved in
key_create_info.algorithm as HA_KEY_ALG_LONG_HASH.
@return FALSE OK
@return TRUE error
*/
static
my_bool init_key_info(THD *thd, Alter_info *alter_info,
HA_CREATE_INFO *create_info,
const handler *file)
{
DBUG_ENTER("init_key_info");
uint max_key_length= file->max_key_length();
uint max_key_part_length= file->max_key_part_length();
for (Key &key: alter_info->key_list)
{
if (key.type == Key::FOREIGN_KEY)
continue;
int parts_added= append_system_key_parts(thd, create_info, &key);
if (parts_added < 0)
DBUG_RETURN(true);
bool is_hash_field_needed= false;
for (Key_part_spec &kp: key.columns)
{
if (init_key_part_spec(thd, alter_info, file, key, kp,
max_key_length, max_key_part_length,
&is_hash_field_needed))
DBUG_RETURN(TRUE);
key.length+= kp.length;
if (key.length > max_key_length && key.type == Key::UNIQUE)
is_hash_field_needed= true; // for case "a BLOB UNIQUE"
if (key.length > max_key_length && key.type != Key::FULLTEXT &&
!is_hash_field_needed)
{
my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length);
DBUG_RETURN(TRUE);
}
KEY_CREATE_INFO *key_cinfo= &key.key_create_info;
if (is_hash_field_needed)
{
if (key_cinfo->algorithm == HA_KEY_ALG_UNDEF)
key_cinfo->algorithm= HA_KEY_ALG_LONG_HASH;
if (key_cinfo->algorithm != HA_KEY_ALG_HASH &&
key_cinfo->algorithm != HA_KEY_ALG_LONG_HASH)
{
my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length);
DBUG_RETURN(TRUE);
}
}
}
}
DBUG_RETURN(FALSE);
}
/*
Preparation for table creation
@@ -3592,7 +3889,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
{
const char *key_name;
Create_field *sql_field,*dup_field;
uint field,null_fields,max_key_length;
uint field,null_fields;
ulong record_offset= 0;
KEY_PART_INFO *key_part_info;
int field_no,dup_no;
@@ -3603,7 +3900,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
int select_field_count= C_CREATE_SELECT(create_table_mode);
bool tmp_table= create_table_mode == C_ALTER_TABLE;
const bool create_simple= thd->lex->create_simple();
bool is_hash_field_needed= false;
const Column_derived_attributes dattr(create_info->default_table_charset);
const Column_bulk_alter_attributes
battr(create_info->alter_table_convert_to_charset);
@@ -3639,7 +3935,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
create_info->versioned());
null_fields= 0;
create_info->varchar= 0;
max_key_length= file->max_key_length();
/* Handle creation of sequences */
if (create_info->sequence)
@@ -3838,6 +4133,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
/* special marker for keys to be ignored */
static char ignore_key[1];
if (init_key_info(thd, alter_info, create_info, file))
DBUG_RETURN(TRUE);
/* Calculate number of key segements */
*key_count= 0;
@@ -3967,10 +4265,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_info->name.length= strlen(key_name);
key->name= key_info->name;
int parts_added= append_system_key_parts(thd, create_info, key);
if (parts_added < 0)
DBUG_RETURN(true);
key_parts += parts_added;
key_info++;
}
tmp=file->max_keys();
@@ -3989,11 +4283,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_number=0;
for (; (key=key_iterator++) ; key_number++)
{
uint key_length=0;
Create_field *auto_increment_key= 0;
Key_part_spec *column;
is_hash_field_needed= false;
bool is_hash_field_needed= key->key_create_info.algorithm
== HA_KEY_ALG_LONG_HASH;
if (key->name.str == ignore_key)
{
/* ignore redundant keys */
@@ -4004,6 +4298,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
break;
}
if (key_check_without_overlaps(thd, create_info, alter_info, *key))
DBUG_RETURN(true);
switch (key->type) {
case Key::MULTIPLE:
key_info->flags= 0;
@@ -4034,10 +4331,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (key->generated)
key_info->flags|= HA_GENERATED_KEY;
key_info->key_length= key->length;
key_info->user_defined_key_parts=(uint8) key->columns.elements;
key_info->key_part=key_part_info;
key_info->usable_key_parts= key_number;
key_info->algorithm= key->key_create_info.algorithm;
key_info->without_overlaps= key->without_overlaps;
key_info->option_list= key->option_list;
extend_option_list(thd, create_info->db_type, !key->old,
&key_info->option_list, create_info->db_type->index_options);
@@ -4121,37 +4420,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
CHARSET_INFO *ft_key_charset=0; // for FULLTEXT
for (uint column_nr=0 ; (column=cols++) ; column_nr++)
{
Key_part_spec *dup_column;
it.rewind();
field=0;
while ((sql_field=it++) &&
lex_string_cmp(scs, &column->field_name, &sql_field->field_name))
field++;
/*
Either field is not present or field visibility is > INVISIBLE_USER
*/
if (!sql_field || (sql_field->invisible > INVISIBLE_USER &&
!column->generated))
{
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
if (sql_field->invisible > INVISIBLE_USER &&
!(sql_field->flags & VERS_SYSTEM_FIELD) &&
!key->invisible && DBUG_EVALUATE_IF("test_invisible_index", 0, 1))
{
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
while ((dup_column= cols2++) != column)
{
if (!lex_string_cmp(scs, &column->field_name, &dup_column->field_name))
{
my_error(ER_DUP_FIELDNAME, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
}
if (sql_field->compression_method())
{
@@ -4161,12 +4434,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
cols2.rewind();
switch(key->type) {
switch(key->type)
{
case Key::FULLTEXT:
if (sql_field->type_handler()->Key_part_spec_init_ft(column,
*sql_field) ||
(ft_key_charset && sql_field->charset != ft_key_charset))
if (ft_key_charset && sql_field->charset != ft_key_charset)
{
my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name.str);
DBUG_RETURN(-1);
@@ -4174,64 +4445,46 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
ft_key_charset= sql_field->charset;
break;
case Key::SPATIAL:
if (sql_field->type_handler()->Key_part_spec_init_spatial(column,
*sql_field) ||
sql_field->check_vcol_for_key(thd))
DBUG_RETURN(TRUE);
if (!(sql_field->flags & NOT_NULL_FLAG))
{
my_message(ER_SPATIAL_CANT_HAVE_NULL,
ER_THD(thd, ER_SPATIAL_CANT_HAVE_NULL), MYF(0));
DBUG_RETURN(TRUE);
}
break;
case Key::PRIMARY:
if (sql_field->vcol_info)
{
my_error(ER_PRIMARY_KEY_BASED_ON_GENERATED_COLUMN, MYF(0));
DBUG_RETURN(TRUE);
}
if (sql_field->type_handler()->Key_part_spec_init_primary(column,
*sql_field,
file))
DBUG_RETURN(TRUE);
if (!(sql_field->flags & NOT_NULL_FLAG))
{
/* Implicitly set primary key fields to NOT NULL for ISO conf. */
/* Implicitly set primary key fields to NOT NULL for ISO conformance. */
sql_field->flags|= NOT_NULL_FLAG;
sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
null_fields--;
}
break;
case Key::MULTIPLE:
if (sql_field->type_handler()->Key_part_spec_init_multiple(column,
*sql_field,
file) ||
sql_field->check_vcol_for_key(thd) ||
key_add_part_check_null(file, key_info, sql_field, column))
DBUG_RETURN(TRUE);
break;
case Key::FOREIGN_KEY:
if (sql_field->type_handler()->Key_part_spec_init_foreign(column,
*sql_field,
file) ||
sql_field->check_vcol_for_key(thd) ||
key_add_part_check_null(file, key_info, sql_field, column))
DBUG_RETURN(TRUE);
break;
case Key::UNIQUE:
if (sql_field->type_handler()->Key_part_spec_init_unique(column,
*sql_field, file,
&is_hash_field_needed) ||
sql_field->check_vcol_for_key(thd) ||
key_add_part_check_null(file, key_info, sql_field, column))
case Key::MULTIPLE:
case Key::FOREIGN_KEY:
if (key_add_part_check_null(file, key_info, sql_field, column))
DBUG_RETURN(TRUE);
if (sql_field->check_vcol_for_key(thd))
DBUG_RETURN(TRUE);
break;
case Key::SPATIAL:
if (!(sql_field->flags & NOT_NULL_FLAG))
{
my_message(ER_SPATIAL_CANT_HAVE_NULL,
ER_THD(thd, ER_SPATIAL_CANT_HAVE_NULL), MYF(0));
DBUG_RETURN(TRUE);
}
if (sql_field->check_vcol_for_key(thd))
DBUG_RETURN(TRUE);
break;
}
for (const Key_part_spec &kp2: key->columns)
{
if (column == &kp2)
break;
if (kp2.field_name.streq(column->field_name))
{
my_error(ER_DUP_FIELDNAME, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
}
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
@@ -4246,111 +4499,21 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_part_info->fieldnr= field;
key_part_info->offset= (uint16) sql_field->offset;
key_part_info->key_type=sql_field->pack_flag;
uint key_part_length= sql_field->type_handler()->
calc_key_length(*sql_field);
if (column->length)
{
if (f_is_blob(sql_field->pack_flag))
{
key_part_length= MY_MIN(column->length,
blob_length_by_type(sql_field->real_field_type())
* sql_field->charset->mbmaxlen);
if (key_part_length > max_key_length ||
key_part_length > file->max_key_part_length())
{
if (key->type == Key::MULTIPLE)
{
key_part_length= MY_MIN(max_key_length, file->max_key_part_length());
/* not a critical problem */
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY),
key_part_length);
/* Align key length to multibyte char boundary */
key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
}
}
}
// Catch invalid use of partial keys
else if (!f_is_geom(sql_field->pack_flag) &&
// is the key partial?
column->length != key_part_length &&
// is prefix length bigger than field length?
(column->length > key_part_length ||
// can the field have a partial key?
!sql_field->type_handler()->type_can_have_key_part() ||
// a packed field can't be used in a partial key
f_is_packed(sql_field->pack_flag) ||
// does the storage engine allow prefixed search?
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
// and is this a 'unique' key?
(key_info->flags & HA_NOSAME))))
{
my_message(ER_WRONG_SUB_KEY, ER_THD(thd, ER_WRONG_SUB_KEY), MYF(0));
DBUG_RETURN(TRUE);
}
else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
key_part_length= column->length;
}
else if (key_part_length == 0 && (sql_field->flags & NOT_NULL_FLAG) &&
!is_hash_field_needed)
{
my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(),
column->field_name.str);
DBUG_RETURN(TRUE);
}
if (key_part_length > file->max_key_part_length() &&
key->type != Key::FULLTEXT)
{
if (key->type == Key::MULTIPLE)
{
key_part_length= file->max_key_part_length();
/* not a critical problem */
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_TOO_LONG_KEY, ER_THD(thd, ER_TOO_LONG_KEY),
key_part_length);
/* Align key length to multibyte char boundary */
key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
}
else
{
if (key->type != Key::UNIQUE)
{
key_part_length= MY_MIN(max_key_length, file->max_key_part_length());
my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
DBUG_RETURN(TRUE);
}
}
}
if (key->type == Key::UNIQUE
&& key_part_length > MY_MIN(max_key_length,
file->max_key_part_length()))
is_hash_field_needed= true;
/* We can not store key_part_length more then 2^16 - 1 in frm */
if (is_hash_field_needed && column->length > UINT_MAX16)
{
my_error(ER_TOO_LONG_KEYPART, MYF(0), UINT_MAX16);
DBUG_RETURN(TRUE);
}
else
key_part_info->length= (uint16) key_part_length;
key_part_info->length= column->length;
/* Use packed keys for long strings on the first column */
if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
!((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) &&
(key_part_length >= KEY_DEFAULT_PACK_LENGTH) &&
(column->length >= KEY_DEFAULT_PACK_LENGTH) &&
!is_hash_field_needed)
{
key_info->flags|= sql_field->type_handler()->KEY_pack_flags(column_nr);
}
/* Check if the key segment is partial, set the key flag accordingly */
if (key_part_length != sql_field->type_handler()->
if (column->length != sql_field->type_handler()->
calc_key_length(*sql_field) &&
key_part_length != sql_field->type_handler()->max_octet_length())
column->length != sql_field->type_handler()->max_octet_length())
key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
key_length+= key_part_length;
key_part_info++;
}
if (!key_info->name.str || check_column_name(key_info->name.str))
@@ -4360,15 +4523,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
if (key->type == Key::UNIQUE && !(key_info->flags & HA_NULL_PART_KEY))
unique_key=1;
key_info->key_length=(uint16) key_length;
if (key_info->key_length > max_key_length && key->type == Key::UNIQUE)
is_hash_field_needed= true; // for case "a BLOB UNIQUE"
if (key_length > max_key_length && key->type != Key::FULLTEXT &&
!is_hash_field_needed)
{
my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length);
DBUG_RETURN(TRUE);
}
/* Check long unique keys */
if (is_hash_field_needed)
@@ -4380,12 +4534,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_info->name.str);
DBUG_RETURN(TRUE);
}
if (key_info->algorithm != HA_KEY_ALG_UNDEF &&
key_info->algorithm != HA_KEY_ALG_HASH )
{
my_error(ER_TOO_LONG_KEY, MYF(0), max_key_length);
DBUG_RETURN(TRUE);
}
}
if (is_hash_field_needed ||
(key_info->algorithm == HA_KEY_ALG_HASH &&
@@ -4425,40 +4573,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
// Check if a duplicate index is defined.
check_duplicate_key(thd, key, key_info, &alter_info->key_list);
key_info->without_overlaps= key->without_overlaps;
if (key_info->without_overlaps)
{
if (key_info->algorithm == HA_KEY_ALG_HASH ||
key_info->algorithm == HA_KEY_ALG_LONG_HASH)
{
without_overlaps_err:
my_error(ER_KEY_CANT_HAVE_WITHOUT_OVERLAPS, MYF(0), key_info->name.str);
DBUG_RETURN(true);
}
key_iterator2.rewind();
while ((key2 = key_iterator2++))
{
if (key2->type != Key::FOREIGN_KEY)
continue;
DBUG_ASSERT(key != key2);
Foreign_key *fk= (Foreign_key*) key2;
if (fk->update_opt != FK_OPTION_CASCADE)
continue;
for (Key_part_spec& kp: key->columns)
{
for (Key_part_spec& kp2: fk->columns)
{
if (!lex_string_cmp(scs, &kp.field_name, &kp2.field_name))
{
goto without_overlaps_err;
}
}
}
}
create_info->period_info.unique_keys++;
}
key_info++;
}
@@ -4886,20 +5000,6 @@ static int append_system_key_parts(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_PERIOD_NOT_FOUND, MYF(0), key->period.str);
return -1;
}
const auto &period_start= create_info->period_info.period.start;
const auto &period_end= create_info->period_info.period.end;
List_iterator<Key_part_spec> part_it(key->columns);
while (Key_part_spec *key_part= part_it++)
{
if (period_start.streq(key_part->field_name)
|| period_end.streq(key_part->field_name))
{
my_error(ER_KEY_CONTAINS_PERIOD_FIELDS, MYF(0), key->name.str,
key_part->field_name.str);
return -1;
}
}
const auto &period= create_info->period_info.period;
key->columns.push_back(new (thd->mem_root)
Key_part_spec(&period.end, 0, true));