1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

This patch is prerequisite for the 2nd milestone of WL#148 "Foreign keys"

storing and restoring information about foreign keys in the .FRM files and
properly displaying it in SHOW CREATE TABLE output and I_S tables.

The idea of this patch is to change type of Key_part_spec::field_name and
Key::name to LEX_STRING in order to avoid extra strlen() calls during
semantic analysis and statement execution, particularly, in code to be
implemented on the 2nd milestone of WL#148.

Note that since we are not using LEX_STRING everywhere yet (e.g. in
Create_field and KEY) and we want to limit scope of our changes we
have to do strlen() in places where we create Key and Key_part_spec
instances from objects using plain (char*) for strings. These calls
will go away during the process of further (char*) -> LEX_STRING
refactoring.

We have introduced these changes in 6.0 and backported them to 5.5
tree to make people aware of these changes as early as possible and
to simplify merges with mysql-fk and mysql-6.1-fk trees.

No test case is needed since this patch does not introduce any
user visible changes.

sql/sql_class.cc:
  Key_part_spec::field_name is now LEX_STRING. Adjusted code accordingly.
sql/sql_class.h:
  Changed type of Key_part_spec::field_name and Key::name to LEX_STRING in
  order to avoid extra strlen() calls in code responsible for semantic
  analysis and statement execution (e.g. in future code responsible for
  saving/restoring info about foreign keys).
sql/sql_lex.cc:
  Moved null_lex_str from sql_yacc.yy to sql_lex.cc and added its
  declaration to sql_lex.h to make it accessible in other SQL-layer
  modules (e.g. sql_parse.cc).
sql/sql_lex.h:
  Made null_lex_str accessible from outside of sql_lex.cc.
sql/sql_parse.cc:
  Key_part_spec::field_name and Key::name are now LEX_STRING. Adjusted
  code accordingly.
sql/sql_table.cc:
  Adjusted code to accomodate change of type to LEX_STRING for
  Key_part_spec::field_name and Key::name.
sql/sql_yacc.yy:
  Now Key::name and Key_part_spec::field_name are LEX_STRINGs. Adjusted
  grammar to be able properly initialize them. This should allow us to
  save on some strlen() calls during later stages of statement execution.
This commit is contained in:
Dmitry Lenev
2009-10-09 18:29:51 +04:00
parent 0da357645c
commit c0221b0e95
7 changed files with 76 additions and 58 deletions

View File

@ -2877,9 +2877,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
while ((key=key_iterator++))
{
DBUG_PRINT("info", ("key name: '%s' type: %d", key->name ? key->name :
DBUG_PRINT("info", ("key name: '%s' type: %d", key->name.str ? key->name.str :
"(none)" , key->type));
LEX_STRING key_name_str;
if (key->type == Key::FOREIGN_KEY)
{
fk_key_count++;
@ -2888,7 +2887,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
fk_key->ref_columns.elements != fk_key->columns.elements)
{
my_error(ER_WRONG_FK_DEF, MYF(0),
(fk_key->name ? fk_key->name : "foreign key without name"),
(fk_key->name.str ? fk_key->name.str :
"foreign key without name"),
ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
DBUG_RETURN(TRUE);
}
@ -2901,12 +2901,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
DBUG_RETURN(TRUE);
}
key_name_str.str= (char*) key->name;
key_name_str.length= key->name ? strlen(key->name) : 0;
if (check_string_char_length(&key_name_str, "", NAME_CHAR_LEN,
if (check_string_char_length(&key->name, "", NAME_CHAR_LEN,
system_charset_info, 1))
{
my_error(ER_TOO_LONG_IDENT, MYF(0), key->name);
my_error(ER_TOO_LONG_IDENT, MYF(0), key->name.str);
DBUG_RETURN(TRUE);
}
key_iterator2.rewind ();
@ -2920,7 +2918,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
Then we do not need the generated shorter key.
*/
if ((key2->type != Key::FOREIGN_KEY &&
key2->name != ignore_key &&
key2->name.str != ignore_key &&
!foreign_key_prefix(key, key2)))
{
/* TODO: issue warning message */
@ -2928,10 +2926,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
if (!key2->generated ||
(key->generated && key->columns.elements <
key2->columns.elements))
key->name= ignore_key;
key->name.str= ignore_key;
else
{
key2->name= ignore_key;
key2->name.str= ignore_key;
key_parts-= key2->columns.elements;
(*key_count)--;
}
@ -2939,14 +2937,14 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
}
}
if (key->name != ignore_key)
if (key->name.str != ignore_key)
key_parts+=key->columns.elements;
else
(*key_count)--;
if (key->name && !tmp_table && (key->type != Key::PRIMARY) &&
!my_strcasecmp(system_charset_info,key->name,primary_key_name))
if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
!my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
{
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
DBUG_RETURN(TRUE);
}
}
@ -2969,12 +2967,12 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
uint key_length=0;
Key_part_spec *column;
if (key->name == ignore_key)
if (key->name.str == ignore_key)
{
/* ignore redundant keys */
do
key=key_iterator++;
while (key && key->name == ignore_key);
while (key && key->name.str == ignore_key);
if (!key)
break;
}
@ -3087,22 +3085,22 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
field=0;
while ((sql_field=it++) &&
my_strcasecmp(system_charset_info,
column->field_name,
column->field_name.str,
sql_field->field_name))
field++;
if (!sql_field)
{
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name);
my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
while ((dup_column= cols2++) != column)
{
if (!my_strcasecmp(system_charset_info,
column->field_name, dup_column->field_name))
column->field_name.str, dup_column->field_name.str))
{
my_printf_error(ER_DUP_FIELDNAME,
ER(ER_DUP_FIELDNAME),MYF(0),
column->field_name);
column->field_name.str);
DBUG_RETURN(TRUE);
}
}
@ -3116,7 +3114,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet
(ft_key_charset && sql_field->charset != ft_key_charset))
{
my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name);
my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name.str);
DBUG_RETURN(-1);
}
ft_key_charset=sql_field->charset;
@ -3144,7 +3142,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
{
if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
{
my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name);
my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
@ -3152,7 +3150,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
column->length= 25;
if (!column->length)
{
my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name);
my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
}
@ -3183,7 +3181,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_info->flags|= HA_NULL_PART_KEY;
if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
{
my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name);
my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
if (key->type == Key::SPATIAL)
@ -3256,7 +3254,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
else if (length == 0)
{
my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name);
my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str);
DBUG_RETURN(TRUE);
}
if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
@ -3314,7 +3312,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
key_name=primary_key_name;
primary_key=1;
}
else if (!(key_name = key->name))
else if (!(key_name= key->name.str))
key_name=make_unique_key_name(sql_field->field_name,
*key_info_buffer, key_info);
if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
@ -6244,6 +6242,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
key_part_length /= key_part->field->charset()->mbmaxlen;
key_parts.push_back(new Key_part_spec(cfield->field_name,
strlen(cfield->field_name),
key_part_length));
}
if (key_parts.elements)
@ -6273,7 +6272,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
else
key_type= Key::MULTIPLE;
key= new Key(key_type, key_name,
key= new Key(key_type, key_name, strlen(key_name),
&key_create_info,
test(key_info->flags & HA_GENERATED_KEY),
key_parts);
@ -6286,10 +6285,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{
if (key->type != Key::FOREIGN_KEY)
new_key_list.push_back(key);
if (key->name &&
!my_strcasecmp(system_charset_info,key->name,primary_key_name))
if (key->name.str &&
!my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
{
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
goto err;
}
}