List:Commits« Previous MessageNext Message »
From:Dmitry Lenev Date:December 10 2008 7:55pm
Subject:bzr commit into mysql-6.1-fk branch (dlenev:2698) WL#148
View as plain text  
#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#148Dmitry Lenev10 Dec