Bug#18776592 INNODB: FAILING ASSERTION: PRIMARY_KEY_NO == -1 ||
PRIMARY_KEY_NO == 0 This bug is a backport of the following revision of 5.6 source tree: # committer: Gopal Shankar <gopal.shankar@oracle.com> # branch nick: priKey56 # timestamp: Wed 2013-05-29 11:11:46 +0530 # message: # Bug#16368875 INNODB: FAILING ASSERTION:
This commit is contained in:
parent
6cb3ca5996
commit
119984db0c
@ -3383,7 +3383,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
CHARSET_INFO *ft_key_charset=0; // for FULLTEXT
|
CHARSET_INFO *ft_key_charset=0; // for FULLTEXT
|
||||||
for (uint column_nr=0 ; (column=cols++) ; column_nr++)
|
for (uint column_nr=0 ; (column=cols++) ; column_nr++)
|
||||||
{
|
{
|
||||||
uint length;
|
|
||||||
Key_part_spec *dup_column;
|
Key_part_spec *dup_column;
|
||||||
|
|
||||||
it.rewind();
|
it.rewind();
|
||||||
@ -3515,30 +3514,40 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
key_part_info->fieldnr= field;
|
key_part_info->fieldnr= field;
|
||||||
key_part_info->offset= (uint16) sql_field->offset;
|
key_part_info->offset= (uint16) sql_field->offset;
|
||||||
key_part_info->key_type=sql_field->pack_flag;
|
key_part_info->key_type=sql_field->pack_flag;
|
||||||
length= sql_field->key_length;
|
uint key_part_length= sql_field->key_length;
|
||||||
|
|
||||||
if (column->length)
|
if (column->length)
|
||||||
{
|
{
|
||||||
if (f_is_blob(sql_field->pack_flag))
|
if (f_is_blob(sql_field->pack_flag))
|
||||||
{
|
{
|
||||||
if ((length=column->length) > max_key_length ||
|
key_part_length= column->length;
|
||||||
length > file->max_key_part_length())
|
/*
|
||||||
|
There is a possibility that the given prefix length is less
|
||||||
|
than the engine max key part length, but still greater
|
||||||
|
than the BLOB field max size. We handle this case
|
||||||
|
using the max_field_size variable below.
|
||||||
|
*/
|
||||||
|
uint max_field_size= sql_field->key_length * sql_field->charset->mbmaxlen;
|
||||||
|
if ((max_field_size && key_part_length > max_field_size) ||
|
||||||
|
key_part_length > max_key_length ||
|
||||||
|
key_part_length > file->max_key_part_length())
|
||||||
{
|
{
|
||||||
length=min(max_key_length, file->max_key_part_length());
|
// Given prefix length is too large, adjust it.
|
||||||
|
key_part_length= min(max_key_length, file->max_key_part_length());
|
||||||
|
if (max_field_size)
|
||||||
|
key_part_length= min(key_part_length, max_field_size);
|
||||||
if (key->type == Key::MULTIPLE)
|
if (key->type == Key::MULTIPLE)
|
||||||
{
|
{
|
||||||
/* not a critical problem */
|
/* not a critical problem */
|
||||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
|
ER_TOO_LONG_KEY, ER(ER_TOO_LONG_KEY),
|
||||||
length);
|
key_part_length);
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
||||||
ER_TOO_LONG_KEY, warn_buff);
|
|
||||||
/* Align key length to multibyte char boundary */
|
/* Align key length to multibyte char boundary */
|
||||||
length-= length % sql_field->charset->mbmaxlen;
|
key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_LONG_KEY,MYF(0),length);
|
my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3546,9 +3555,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
// Catch invalid use of partial keys
|
// Catch invalid use of partial keys
|
||||||
else if (!f_is_geom(sql_field->pack_flag) &&
|
else if (!f_is_geom(sql_field->pack_flag) &&
|
||||||
// is the key partial?
|
// is the key partial?
|
||||||
column->length != length &&
|
column->length != key_part_length &&
|
||||||
// is prefix length bigger than field length?
|
// is prefix length bigger than field length?
|
||||||
(column->length > length ||
|
(column->length > key_part_length ||
|
||||||
// can the field have a partial key?
|
// can the field have a partial key?
|
||||||
!Field::type_can_have_key_part (sql_field->sql_type) ||
|
!Field::type_can_have_key_part (sql_field->sql_type) ||
|
||||||
// a packed field can't be used in a partial key
|
// a packed field can't be used in a partial key
|
||||||
@ -3562,38 +3571,37 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
|
else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
|
||||||
length=column->length;
|
key_part_length= column->length;
|
||||||
}
|
}
|
||||||
else if (length == 0)
|
else if (key_part_length == 0)
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str);
|
my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
|
if (key_part_length > file->max_key_part_length() &&
|
||||||
|
key->type != Key::FULLTEXT)
|
||||||
{
|
{
|
||||||
length= file->max_key_part_length();
|
key_part_length= file->max_key_part_length();
|
||||||
if (key->type == Key::MULTIPLE)
|
if (key->type == Key::MULTIPLE)
|
||||||
{
|
{
|
||||||
/* not a critical problem */
|
/* not a critical problem */
|
||||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
|
ER_TOO_LONG_KEY, ER(ER_TOO_LONG_KEY),
|
||||||
length);
|
key_part_length);
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
|
||||||
ER_TOO_LONG_KEY, warn_buff);
|
|
||||||
/* Align key length to multibyte char boundary */
|
/* Align key length to multibyte char boundary */
|
||||||
length-= length % sql_field->charset->mbmaxlen;
|
key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_LONG_KEY,MYF(0),length);
|
my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key_part_info->length=(uint16) length;
|
key_part_info->length= (uint16) key_part_length;
|
||||||
/* Use packed keys for long strings on the first column */
|
/* Use packed keys for long strings on the first column */
|
||||||
if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
|
if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
|
||||||
!((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) &&
|
!((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) &&
|
||||||
(length >= KEY_DEFAULT_PACK_LENGTH &&
|
(key_part_length >= KEY_DEFAULT_PACK_LENGTH &&
|
||||||
(sql_field->sql_type == MYSQL_TYPE_STRING ||
|
(sql_field->sql_type == MYSQL_TYPE_STRING ||
|
||||||
sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
|
sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
|
||||||
sql_field->pack_flag & FIELDFLAG_BLOB)))
|
sql_field->pack_flag & FIELDFLAG_BLOB)))
|
||||||
@ -3605,10 +3613,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
key_info->flags|= HA_PACK_KEY;
|
key_info->flags|= HA_PACK_KEY;
|
||||||
}
|
}
|
||||||
/* Check if the key segment is partial, set the key flag accordingly */
|
/* Check if the key segment is partial, set the key flag accordingly */
|
||||||
if (length != sql_field->key_length)
|
if (key_part_length != sql_field->key_length)
|
||||||
key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
|
key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
|
||||||
|
|
||||||
key_length+=length;
|
key_length+= key_part_length;
|
||||||
key_part_info++;
|
key_part_info++;
|
||||||
|
|
||||||
/* Create the key name based on the first column (if not given) */
|
/* Create the key name based on the first column (if not given) */
|
||||||
|
22
sql/table.cc
22
sql/table.cc
@ -1525,11 +1525,23 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
primary_key=key;
|
primary_key=key;
|
||||||
for (i=0 ; i < keyinfo->key_parts ;i++)
|
for (i=0 ; i < keyinfo->key_parts ;i++)
|
||||||
{
|
{
|
||||||
uint fieldnr= key_part[i].fieldnr;
|
DBUG_ASSERT(key_part[i].fieldnr > 0);
|
||||||
if (!fieldnr ||
|
// Table field corresponding to the i'th key part.
|
||||||
share->field[fieldnr-1]->null_ptr ||
|
Field *table_field= share->field[key_part[i].fieldnr - 1];
|
||||||
share->field[fieldnr-1]->key_length() !=
|
|
||||||
key_part[i].length)
|
/*
|
||||||
|
If the key column is of NOT NULL BLOB type, then it
|
||||||
|
will definitly have key prefix. And if key part prefix size
|
||||||
|
is equal to the BLOB column max size, then we can promote
|
||||||
|
it to primary key.
|
||||||
|
*/
|
||||||
|
if (!table_field->real_maybe_null() &&
|
||||||
|
table_field->type() == MYSQL_TYPE_BLOB &&
|
||||||
|
table_field->field_length == key_part[i].length)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (table_field->real_maybe_null() ||
|
||||||
|
table_field->key_length() != key_part[i].length)
|
||||||
{
|
{
|
||||||
primary_key= MAX_KEY; // Can't be used
|
primary_key= MAX_KEY; // Can't be used
|
||||||
break;
|
break;
|
||||||
|
@ -2692,6 +2692,19 @@ i_s_innodb_buffer_page_fill(
|
|||||||
table_name = mem_heap_strdup(heap,
|
table_name = mem_heap_strdup(heap,
|
||||||
index->table_name);
|
index->table_name);
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("mysql_test_print_index_type",
|
||||||
|
{
|
||||||
|
char idx_type[3];
|
||||||
|
|
||||||
|
ut_snprintf(idx_type,
|
||||||
|
sizeof(idx_type),
|
||||||
|
"%d",
|
||||||
|
index->type);
|
||||||
|
|
||||||
|
index_name=mem_heap_strcat(heap,
|
||||||
|
index_name,
|
||||||
|
idx_type);
|
||||||
|
};);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_exit(&dict_sys->mutex);
|
mutex_exit(&dict_sys->mutex);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user