#At file:///home/dlenev/src/bzr/mysql-6.1-mil8-3/
2698 Dmitry Lenev 2008-12-10
WL#148 "Foreign keys".
Milestone #8 "DML words: INSERT, UPDATE, DELETE, no EOS checks".
Work in progress. After review fixes.
modified:
sql/fk.cc
per-file messages:
sql/fk.cc
Moved code responsible for finding parent and supporting keys
into separate functions.
=== modified file 'sql/fk.cc'
--- a/sql/fk.cc 2008-12-10 17:04:31 +0000
+++ b/sql/fk.cc 2008-12-10 19:55:29 +0000
@@ -506,6 +506,28 @@ Fk_constraint_list::cascading_action_chi
/**
+ Find table's index by its name.
+
+ @param table TABLE which index should be found.
+ @param name Name of index to be found.
+
+ @retval 0 Error, no suitable index found.
+ @retval non-0 Pointer to the KEY object for the index.
+*/
+
+static KEY* find_key_by_name(TABLE *table, LEX_STRING &name)
+{
+ KEY *key, *key_end= table->key_info + table->s->keys;
+ for (key= table->key_info; key != key_end; key++)
+ {
+ if (!my_strcasecmp(system_charset_info, name.str, key->name))
+ break;
+ }
+ return (key != key_end) ? key : 0;
+}
+
+
+/**
Prepare runtime context for checks performed for the foreign key
then statement modifies child table.
@@ -518,7 +540,6 @@ bool Foreign_key_child_rcontext::prepare
TABLE_LIST parent_table_list;
Query_tables_list query_tables_list_backup;
LEX *lex= thd->lex;
- KEY *key_end;
uchar *key_col_pos;
uint i;
@@ -557,14 +578,8 @@ bool Foreign_key_child_rcontext::prepare
m_parent_table= parent_table_list.table;
/* Find a PRIMARY/UNIQUE index which we will used for lookups in parent. */
- key_end= m_parent_table->key_info + m_parent_table->s->keys;
- for (key= m_parent_table->key_info; key != key_end; key++)
- {
- if (!my_strcasecmp(system_charset_info,
- m_fk_share->parent_constraint_name.str, key->name))
- break;
- }
- if (key == key_end)
+ if (!(key= find_key_by_name(m_parent_table,
+ m_fk_share->parent_constraint_name)))
{
/*
This should be an impossible situation (i.e. data-dictionary is
@@ -736,6 +751,60 @@ bool Foreign_key_child_rcontext::check_p
/**
+ Find table's index which contains all columns from the list
+ and nothing else.
+
+ @param table TABLE which index should be found.
+ @param columns List of columns which it should contain.
+
+ @retval 0 Error, no suitable index found.
+ @retval non-0 Pointer to the KEY object for the index.
+*/
+
+static KEY* find_supporting_key(TABLE *table, List<LEX_STRING> &columns)
+{
+ KEY *key, *key_end= table->key_info + table->s->keys;
+
+ for (key= table->key_info; key != key_end; key++)
+ {
+ if (columns.elements == key->key_parts)
+ {
+ List_iterator<LEX_STRING> col_it(columns);
+ LEX_STRING *col;
+ while ((col= col_it++))
+ {
+ uint j;
+ for (j= 0; j < key->key_parts; j++)
+ {
+ if (key->key_part[j].key_part_flag & HA_PART_KEY_SEG)
+ {
+ /*
+ This index contains key part which covers only prefix of
+ column, therefore it cannot serve as supporting index.
+ Fast forward to the next index.
+ */
+ j= key->key_parts;
+ break;
+ }
+ if (!my_strcasecmp(system_charset_info,
+ col->str, key->key_part[j].field->field_name))
+ break;
+ }
+ if (j == key->key_parts)
+ break;
+ }
+ if (!col)
+ {
+ /* No unmatched columns, we have found supporting index. */
+ break;
+ }
+ }
+ }
+ return (key != key_end) ? key : 0;
+}
+
+
+/**
Prepare runtime context for checks and cascading actions performed
for the foreign key then statement modifies parent table.
@@ -751,7 +820,6 @@ bool Foreign_key_parent_rcontext::prepar
{
Query_tables_list query_tables_list_backup;
LEX *lex= thd->lex;
- KEY *key_end;
uchar *key_col_pos;
uint i;
@@ -808,45 +876,8 @@ bool Foreign_key_parent_rcontext::prepar
m_child_table= m_child_table_list.table;
-
/* Find index which supports this foreign key. */
- key_end= m_child_table->key_info + m_child_table->s->keys;
- for (key= m_child_table->key_info; key != key_end; key++)
- {
- if (m_fk_share->child_columns.elements == key->key_parts)
- {
- List_iterator<LEX_STRING> col_it(m_fk_share->child_columns);
- LEX_STRING *col;
- while ((col= col_it++))
- {
- uint j;
- for (j= 0; j < key->key_parts; j++)
- {
- if (key->key_part[j].key_part_flag & HA_PART_KEY_SEG)
- {
- /*
- This index contains key part which covers only prefix of
- column, therefore it cannot serve as supporting index.
- Fast forward to the next index.
- */
- j= key->key_parts;
- break;
- }
- if (!my_strcasecmp(system_charset_info,
- col->str, key->key_part[j].field->field_name))
- break;
- }
- if (j == key->key_parts)
- break;
- }
- if (!col)
- {
- /* No unmatched columns, we have found supporting index. */
- break;
- }
- }
- }
- if (key == key_end)
+ if (!(key= find_supporting_key(m_child_table, m_fk_share->child_columns)))
{
/*
Again this should be impossible (or data-dictionary corruption) but
| Thread |
|---|
| • bzr commit into mysql-6.1-fk branch (dlenev:2698) WL#148 | Dmitry Lenev | 10 Dec |