List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:December 12 2008 6:59pm
Subject:bzr commit into mysql-6.1-fk branch (kostja:2710) WL#148
View as plain text  
#At file:///opt/local/work/mysql-6.1-fk-stage/

 2710 Konstantin Osipov	2008-12-12
      WL#148, Milestone 8, Part 1.
      Review fixes.
      Dont' add cascading keys to check parent list.
      Renames.
modified:
  sql/fk.cc
  sql/fk.h
  sql/sql_delete.cc
  sql/sql_insert.cc
  sql/sql_load.cc
  sql/sql_update.cc

=== modified file 'sql/fk.cc'
--- a/sql/fk.cc	2008-12-12 17:33:34 +0000
+++ b/sql/fk.cc	2008-12-12 18:58:51 +0000
@@ -222,13 +222,17 @@ private:
 */
 
 bool
-Fk_constraint_list::prepare_for_insert(THD *thd, TABLE *table,
-                                       MY_BITMAP *changed_column_map)
+Fk_constraint_list::prepare_check_parent(THD *thd, TABLE *table,
+                                         MY_BITMAP *changed_column_map)
 {
   List_iterator<Foreign_key_child_share> fk_it(table->s->fkeys_child);
   Foreign_key_child_share *fk_share;
 
-  m_fkeys_child.empty();
+  /*
+    The list is emptied in the constructor. Prepare must be called only
+    once.
+  */
+  DBUG_ASSERT(m_fkeys_child.is_empty());
 
   /* No foreign key checks should be performed when FOREIGN_KEY_CHECKS is 0. */
   if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)
@@ -273,15 +277,15 @@ Fk_constraint_list::prepare_for_insert(T
 */
 
 bool
-Fk_constraint_list::prepare_for_update(THD *thd, TABLE *table,
-                                       bool old_row_is_record1,
-                                       MY_BITMAP *changed_column_map)
+Fk_constraint_list::prepare_check_child(THD *thd, TABLE *table,
+                                        bool old_row_is_record1,
+                                        MY_BITMAP *changed_column_map)
 {
   List_iterator<Foreign_key_parent_share> fk_it(table->s->fkeys_parent);
   Foreign_key_parent_share *fk_share;
 
-  m_fkeys_parent.empty();
-  m_fkeys_parent_cascade.empty();
+  DBUG_ASSERT(m_fkeys_parent.is_empty());
+  DBUG_ASSERT(m_fkeys_parent_cascade.is_empty());
 
   /* No foreign key checks should be performed when FOREIGN_KEY_CHECKS is 0. */
   if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)
@@ -300,15 +304,14 @@ Fk_constraint_list::prepare_for_update(T
       if (rctx->prepare(old_row_is_record1))
         return TRUE;
 
-      if (m_fkeys_parent.push_back(rctx, thd->mem_root))
-        return TRUE;
-
-      if (rctx->is_cascading() &&
-          (rctx->prepare_cascade() ||
-           m_fkeys_parent_cascade.push_back(rctx, thd->mem_root)))
+      if (rctx->is_cascading())
       {
-        return TRUE;
+        if (rctx->prepare_cascade() ||
+            m_fkeys_parent_cascade.push_back(rctx, thd->mem_root))
+          return TRUE;
       }
+      else if (m_fkeys_parent.push_back(rctx, thd->mem_root))
+        return TRUE;
     }
   }
   return FALSE;
@@ -342,7 +345,7 @@ Fk_constraint_list::do_check_parent_list
     /*
       There's a foreign key defined on this table and we are changing at
       least one of columns participating in it (this is because only such
-      foreign keys were added to the list by prepare_for_insert()).
+      foreign keys were added to the list by prepare_check_parent()).
     */
     if (fk_ctx->check_parent_exists())
       return TRUE;
@@ -412,52 +415,50 @@ Fk_constraint_list::do_check_child_list(
 
   while ((fk_ctx= fkctx_it++))
   {
-    if (fk_ctx->ref_action() == FK_OPTION_NO_ACTION ||
-        fk_ctx->ref_action() == FK_OPTION_RESTRICT)
-    {
-      if (fk_ctx->check_children_exist())
-        return TRUE;
+    DBUG_ASSERT(! fk_ctx->is_cascading());
+
+    if (fk_ctx->check_children_exist())
+      return TRUE;
 
 #ifdef ONCE_EOS_CHECKS_ARE_IMPLEMENTED
+    /*
+      For this constraint, for this row, there is no foreign-key referencing.
+      That is, the handler returned "no child exists".
+    */
+    continue 'for each constraint in constraint list' loop;
+
+      /* Handler returned "a child exists" */
+
+    if (fk_statement_flags&FK_STATEMENT_FLAG_NO_EOS == 0)
+    {
       /*
-        For this constraint, for this row, there is no foreign-key referencing.
-        That is, the handler returned "no child exists".
+        End-of-statement check is possible. But that doesn't matter
+        unless it's a NO ACTION constraint.
       */
-      continue 'for each constraint in constraint list' loop
+      if (UPDATE && constraint->fk_on_update_referential_action==FK_FLAG_NO_ACTION)
+        or (DELETE && constraint->fk_on_delete_referential_action==FK_FLAG_NO_ACTION)
+          need_eos_check= true;
+      continue 'for each constraint in constraint list' loop;
+      else /* referential_action is RESTRICT */
+        error(ER_FK_CHILD_VALUE_EXISTS);
+    }
 
-        /* Handler returned "a child exists" */
+    /* End-of-statement check is not possible. */
 
-        if (fk_statement_flags&FK_STATEMENT_FLAG_NO_EOS == 0)
-        {
-          /*
-            End-of-statement check is possible. But that doesn't matter
-            unless it's a NO ACTION constraint.
-          */
-          if (UPDATE && constraint->fk_on_update_referential_action==FK_FLAG_NO_ACTION)
-            or (DELETE && constraint->fk_on_delete_referential_action==FK_FLAG_NO_ACTION)
-              need_eos_check= true;
+    if (child->relationship == SELF_REFERENCING_TABLE)
+      if (child->is_self_referencing_relationship)
+        if (fk_check_record_in_memory(record) == TRUE)
+          /* The child row is in memory. That is, it's being deleted too. */
+          /* This is the reverse of the check we could make when inserting. */
           continue 'for each constraint in constraint list' loop;
-          else /* referential_action is RESTRICT */
-            error(ER_FK_CHILD_VALUE_EXISTS);
-        }
-
-      /* End-of-statement check is not possible. */
-
-      if (child->relationship == SELF_REFERENCING_TABLE)
-        if (child->is_self_referencing_relationship)
-          if (fk_check_record_in_memory(record) == TRUE)
-            /* The child row is in memory. That is, it's being deleted too. */
-            /* This is the reverse of the check we could make when inserting. */
-            continue 'for each constraint in constraint list' loop;
 
-      /*
-        End-of-statement check is not possible, and there is no
-        self-reference -- so the effect is "as if referential action is
-        RESTRICT".
-      */
-      error(ER_FK_CHILD_VALUE_EXISTS);
+    /*
+      End-of-statement check is not possible, and there is no
+      self-reference -- so the effect is "as if referential action is
+      RESTRICT".
+    */
+    error(ER_FK_CHILD_VALUE_EXISTS);
 #endif
-    }
   }
 #ifdef ONCE_EOS_CHECKS_ARE_IMPLEMENTED
   if (need_eos_check)
@@ -1046,8 +1047,8 @@ bool Foreign_key_parent_rcontext::prepar
     if (! m_cascade_fk_list)
       return TRUE;
 
-    if (m_cascade_fk_list->prepare_for_update(m_thd, m_child_table, FALSE,
-                                              &m_child_table->s->all_set))
+    if (m_cascade_fk_list->prepare_check_child(m_thd, m_child_table, FALSE,
+                                               &m_child_table->s->all_set))
       return TRUE;
   }
   else if (m_ref_action != FK_OPTION_NO_ACTION &&
@@ -1066,10 +1067,10 @@ bool Foreign_key_parent_rcontext::prepar
     if (! m_cascade_fk_list)
       return TRUE;
 
-    if (m_cascade_fk_list->prepare_for_insert(m_thd, m_child_table,
-                                              m_child_table->write_set) ||
-        m_cascade_fk_list->prepare_for_update(m_thd, m_child_table, TRUE,
-                                              m_child_table->write_set))
+    if (m_cascade_fk_list->prepare_check_parent(m_thd, m_child_table,
+                                                m_child_table->write_set) ||
+        m_cascade_fk_list->prepare_check_child(m_thd, m_child_table, TRUE,
+                                               m_child_table->write_set))
       return TRUE;
   }
   return FALSE;

=== modified file 'sql/fk.h'
--- a/sql/fk.h	2008-12-11 23:21:56 +0000
+++ b/sql/fk.h	2008-12-12 18:58:51 +0000
@@ -41,12 +41,12 @@ public:
 
   inline trg_event_type action_type() const { return m_action_type; }
 
-  bool prepare_for_insert(THD *thd, TABLE *table,
-                          MY_BITMAP *changed_column_map);
+  bool prepare_check_parent(THD *thd, TABLE *table,
+                            MY_BITMAP *changed_column_map);
 
-  bool prepare_for_update(THD *thd, TABLE *table,
-                          bool old_row_is_record1,
-                          MY_BITMAP *changed_column_map);
+  bool prepare_check_child(THD *thd, TABLE *table,
+                           bool old_row_is_record1,
+                           MY_BITMAP *changed_column_map);
 
   /** Inline wrappers to speed up the most common case. */
   bool check_parent_list(TABLE *table, bool use_eos)

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2008-12-11 12:26:59 +0000
+++ b/sql/sql_delete.cc	2008-12-12 18:58:51 +0000
@@ -381,7 +381,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
 
   table->mark_columns_needed_for_delete();
 
-  if (fk_list.prepare_for_update(thd, table, FALSE, &table->s->all_set))
+  if (fk_list.prepare_check_child(thd, table, FALSE, &table->s->all_set))
   {
     end_read_record(&info);
     delete select;

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2008-12-12 17:33:34 +0000
+++ b/sql/sql_insert.cc	2008-12-12 18:58:51 +0000
@@ -684,7 +684,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   /* Restore the current context. */
   ctx_state.restore_state(context, table_list);
 
-  if (fk_list.prepare_for_insert(thd, table, &table->s->all_set))
+  if (fk_list.prepare_check_parent(thd, table, &table->s->all_set))
     goto abort;
 
   /*
@@ -3124,7 +3124,7 @@ select_insert::prepare(List<Item> &value
   if (!res)
   {
      prepare_triggers_for_insert_stmt(table);
-     res= fk_list->prepare_for_insert(thd, table, &table->s->all_set);
+     res= fk_list->prepare_check_parent(thd, table, &table->s->all_set);
   }
 
   DBUG_RETURN(res);
@@ -3742,7 +3742,7 @@ select_create::prepare(List<Item> &value
     DBUG_RETURN(1);
 
 #ifdef WL_148_MILESTONE_12
-  if (fk_list->prepare_for_insert(thd, table, &table->s->all_set))
+  if (fk_list->prepare_check_parent(thd, table, &table->s->all_set))
     return TRUE;
 #endif
 

=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc	2008-12-10 13:15:01 +0000
+++ b/sql/sql_load.cc	2008-12-12 18:58:51 +0000
@@ -267,7 +267,7 @@ int mysql_load(THD *thd,sql_exchange *ex
 
   prepare_triggers_for_insert_stmt(table);
 
-  if (fk_list.prepare_for_insert(thd, table, &table->s->all_set))
+  if (fk_list.prepare_check_parent(thd, table, &table->s->all_set))
     DBUG_RETURN(TRUE);
 
   uint tot_length=0;

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2008-12-11 12:26:59 +0000
+++ b/sql/sql_update.cc	2008-12-12 18:58:51 +0000
@@ -545,8 +545,8 @@ int mysql_update(THD *thd,
 
   table->mark_columns_needed_for_update();
 
-  if (fk_list.prepare_for_insert(thd, table, table->write_set) ||
-      fk_list.prepare_for_update(thd, table, TRUE, table->write_set))
+  if (fk_list.prepare_check_parent(thd, table, table->write_set) ||
+      fk_list.prepare_check_child(thd, table, TRUE, table->write_set))
     goto err;
 
   /* Check if we are modifying a key that we are used to search with */

Thread
bzr commit into mysql-6.1-fk branch (kostja:2710) WL#148Konstantin Osipov12 Dec