From: Date: August 6 2008 10:09am Subject: bzr commit into mysql-6.1-fk branch (dlenev:2681) WL#148 List-Archive: http://lists.mysql.com/commits/50976 Message-Id: <20080806080943.87F9B32C00F@mockturtle.local> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///home/dlenev/src/bzr/mysql-6.1-mil4-2/ 2681 Dmitry Lenev 2008-08-06 Additional patch for 4th milestone of WL#148 "Foreign keys" ("Implement meta-data locking for foreign key definitions and make prelocking algorithm aware of foreign keys"). Minor tweaks to names of types, classes and their members to make them follow coding style and make code more clear. Also improved legibility of test case for this milestone. modified: mysql-test/r/foreign_key_all_engines_2.result mysql-test/t/foreign_key_all_engines_2.test sql/fk_dd.cc sql/fk_dd.h sql/mysql_priv.h sql/sql_class.cc sql/sql_class.h sql/sql_lex.h sql/sql_show.cc sql/sql_table.cc sql/sql_yacc.yy sql/unireg.cc per-file messages: mysql-test/r/foreign_key_all_engines_2.result Improve result file legibility by marking places where we switch between connections. mysql-test/t/foreign_key_all_engines_2.test Improve result file legibility by marking places where we switch between connections. sql/fk_dd.cc Renamed FK_FRM_FKS_SECTION_LENGTH_SIZE constant to make its purprose more clear. Adjusted code after renaming Foreign_key class to Foreign_key_child and renaming various members of this and Foreign_key_child/parent_share classes. (code which works with them should be less ambigous and more self-explanatory now). sql/fk_dd.h Fixed function signatures after renaming Foreign_key class to Foreign_key_child. sql/mysql_priv.h Fixed function signatures after renaming Foreign_key class to Foreign_key_child. sql/sql_class.cc Foreign_key_parent/Foreign_key: Renamed "columns" and "ref_columns" members to "child_columns" and "parent_columns" correspondingly. Also renamed "table" and "ref_table" members to "child_table" and "parent_table". Renamed Foreign_key to Foreign_key_child to emphasize its symmetry with Foreign_key_parent and also that it contains information to be saved in .FRM of child table. sql/sql_class.h fk_match_opt/fk_option: Renamed to enum_fk_match_opt/enum_fk_option as per coding style. Foreign_key_parent/Foreign_key: Renamed "columns" and "ref_columns" members to "child_columns" and "parent_columns" correspondingly to avoid ambiguity and to make code more self-explanatory. Also for the same reason renamed "table" and "ref_table" members to "child_table" and "parent_table". Renamed Foreign_key to Foreign_key_child to emphasize its symmetry with Foreign_key_parent and also that it contains information to be saved in .FRM of child table. Foreign_key_parent_share/child_share: Renamed "columns" and "ref_columns" members to "child_columns" and "parent_columns" correspondingly to avoid ambiguity and to make code more self-explanatory. sql/sql_lex.h fk_match_opt/fk_option types were renamed to enum_fk_match_opt/ enum_fk_option as per coding style. Foreign_key class was renamed to Foreign_key_child to emphasize its symmetry with Foreign_key_parent class. sql/sql_show.cc Renamed Foreign_key_child_share::columns/ref_columns members to child_columns and parent_columns to avoid ambiguity. sql/sql_table.cc Fix code after renaming Foreign_key class to Foreign_key_child and renaming its various members. sql/sql_yacc.yy Adjusted code after renaming fk_match_opt/fk_option types to enum_fk_match_opt/enum_fk_option and Foreign_key class to Foreign_key_child. sql/unireg.cc Adjusted code after renaming Foreign_key class to Foreign_key_child. === modified file 'mysql-test/r/foreign_key_all_engines_2.result' --- a/mysql-test/r/foreign_key_all_engines_2.result 2008-08-03 10:13:01 +0000 +++ b/mysql-test/r/foreign_key_all_engines_2.result 2008-08-06 08:09:35 +0000 @@ -1,28 +1,50 @@ drop tables if exists t1, t2, t3; create table t1 (pk int primary key) engine=myisam; insert into t1 values (1), (2), (3); +# Switching to connection 'blocker' lock tables t1 read; +# Switching to connection 'default' create table t2 (fk int references t1 (pk)) engine=myisam; +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' +# Switching to connection 'blocker' lock tables t1 write; +# Switching to connection 'default' insert into t2 values (1); +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' +# Switching to connection 'blocker' lock table t1 read; +# Switching to connection 'default' insert into t2 values (2); +# Switching to connection 'blocker' unlock tables; lock table t2 write; +# Switching to connection 'default' update t1 set pk= 4 where pk=3; +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' +# Switching to connection 'blocker' lock table t2 read; +# Switching to connection 'default' update t1 set pk= 5 where pk=4; +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' drop tables t1, t2; create table t1 (pk int primary key) engine=myisam; insert into t1 values (1), (2), (3); create table t2 (fk int references t1 (pk) on delete cascade) engine=myisam; +# Switching to connection 'blocker' lock tables t2 read; +# Switching to connection 'default' delete from t1 where pk=3; +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' drop tables t1, t2; create table t1 (pk int primary key) engine=myisam; insert into t1 values (1); @@ -31,9 +53,13 @@ insert into t2 values (1); create table t3 (fk1 int references t1 (pk) on delete set null, fk2 int references t2 (pk)) engine=myisam; insert into t3 values (1, 1); +# Switching to connection 'blocker' lock table t1 write; +# Switching to connection 'default' insert into t2 values (2); +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' drop tables t1, t2, t3; create table t1 (pk int primary key) engine=myisam; insert into t1 values (1); @@ -43,9 +69,13 @@ create table t3 (fk1 int references t1 ( fk2 int, foreign key (fk1, fk2) references t2 (pk1, pk2)) engine=myisam; insert into t3 values (1, 1); +# Switching to connection 'blocker' lock table t1 write; +# Switching to connection 'default' insert into t2 values (2, 2); +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' drop tables t1, t2, t3; create table t1 (pk int primary key) engine=myisam; insert into t1 values (1); @@ -54,9 +84,13 @@ fk int references t1 (pk) on delete set insert into t2 values (1, 1); create table t3 (fk int references t2 (pk) on delete cascade) engine=myisam; insert into t3 values (1); +# Switching to connection 'blocker' lock table t3 read; +# Switching to connection 'default' delete from t1 where pk= 1; +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' drop tables t1, t2, t3; create table t1 (pk int primary key) engine=myisam; insert into t1 values (1); @@ -67,9 +101,13 @@ create table t3 (fk1 int, fk2 int, foreign key (fk1, fk2) references t2 (pk1, pk2_fk) on update set null) engine=myisam; insert into t3 values (1, 1); +# Switching to connection 'blocker' lock table t3 read; +# Switching to connection 'default' update t1 set pk= 2; +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' drop tables t1, t2, t3; create table t1 (pk int primary key) engine=myisam; insert into t1 values (1), (2); @@ -79,14 +117,22 @@ insert into t2 values (1, 1), (2, 2); create table t3 (fk int references t2 (pk) on update set null) engine=myisam; insert into t3 values (1), (2); create trigger t2_bu before update on t2 for each row set @a:= 1; +# Switching to connection 'blocker' lock table t3 read; +# Switching to connection 'default' delete from t1 where pk=1; +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' drop trigger t2_bu; create trigger t2_bu before update on t2 for each row set new.pk=3; +# Switching to connection 'blocker' lock table t3 read; +# Switching to connection 'default' delete from t1 where pk=2; +# Switching to connection 'blocker' unlock tables; +# Switching to connection 'default' drop tables t1, t2, t3; drop tables if exists t1, t2; create table t1 (s1 int primary key) engine=innodb; === modified file 'mysql-test/t/foreign_key_all_engines_2.test' --- a/mysql-test/t/foreign_key_all_engines_2.test 2008-08-03 10:13:01 +0000 +++ b/mysql-test/t/foreign_key_all_engines_2.test 2008-08-06 08:09:35 +0000 @@ -19,13 +19,16 @@ connect (blocker, localhost, root,,); connection default; create table t1 (pk int primary key) engine=myisam; insert into t1 values (1), (2), (3); +--echo # Switching to connection 'blocker' connection blocker; # Take table-level lock and thus shared metadata lock on parent table lock tables t1 read; +--echo # Switching to connection 'default' connection default; # This statement takes exclusive metadata lock on parent so it # it should be blocked --send create table t2 (fk int references t1 (pk)) engine=myisam +--echo # Switching to connection 'blocker' connection blocker; let $wait_condition= select count(*) = 1 from information_schema.processlist @@ -33,50 +36,65 @@ let $wait_condition= info = "create table t2 (fk int references t1 (pk)) engine=myisam"; --source include/wait_condition.inc unlock tables; +--echo # Switching to connection 'default' connection default; --reap +--echo # Switching to connection 'blocker' connection blocker; # Take table-level write lock on parent table lock tables t1 write; +--echo # Switching to connection 'default' connection default; # This statement should take read lock on parent table and # therefore should be blocked. --send insert into t2 values (1) +--echo # Switching to connection 'blocker' connection blocker; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Table lock" and info = "insert into t2 values (1)"; --source include/wait_condition.inc unlock tables; +--echo # Switching to connection 'default' connection default; --reap +--echo # Switching to connection 'blocker' connection blocker; # Let us check that our check for presence of row in the parent is # compatible with table-level read lock. lock table t1 read; +--echo # Switching to connection 'default' connection default; insert into t2 values (2); +--echo # Switching to connection 'blocker' connection blocker; unlock tables; lock table t2 write; +--echo # Switching to connection 'default' connection default; # Should be blocked since it has to obtain read lock on t2 --send update t1 set pk= 4 where pk=3 +--echo # Switching to connection 'blocker' connection blocker; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Table lock" and info = "update t1 set pk= 4 where pk=3"; --source include/wait_condition.inc unlock tables; +--echo # Switching to connection 'default' connection default; --reap +--echo # Switching to connection 'blocker' connection blocker; lock table t2 read; +--echo # Switching to connection 'default' connection default; # Should not be blocked update t1 set pk= 5 where pk=4; +--echo # Switching to connection 'blocker' connection blocker; unlock tables; +--echo # Switching to connection 'default' connection default; drop tables t1, t2; # This part of test might start failing once we fully implement all checks @@ -84,17 +102,21 @@ drop tables t1, t2; create table t1 (pk int primary key) engine=myisam; insert into t1 values (1), (2), (3); create table t2 (fk int references t1 (pk) on delete cascade) engine=myisam; +--echo # Switching to connection 'blocker' connection blocker; lock tables t2 read; +--echo # Switching to connection 'default' connection default; # Should be blocked since it has to obtain write lock on t1 --send delete from t1 where pk=3 +--echo # Switching to connection 'blocker' connection blocker; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Table lock" and info = "delete from t1 where pk=3"; --source include/wait_condition.inc unlock tables; +--echo # Switching to connection 'default' connection default; --reap drop tables t1, t2; @@ -109,15 +131,19 @@ insert into t2 values (1); create table t3 (fk1 int references t1 (pk) on delete set null, fk2 int references t2 (pk)) engine=myisam; insert into t3 values (1, 1); +--echo # Switching to connection 'blocker' connection blocker; # This will implicitly lock t3 for update, but should not # lock t2 as cascading change to t3 won't affect t3.fk2. lock table t1 write; +--echo # Switching to connection 'default' connection default; # Should not be blocked insert into t2 values (2); +--echo # Switching to connection 'blocker' connection blocker; unlock tables; +--echo # Switching to connection 'default' connection default; drop tables t1, t2, t3; create table t1 (pk int primary key) engine=myisam; @@ -128,19 +154,23 @@ create table t3 (fk1 int references t1 ( fk2 int, foreign key (fk1, fk2) references t2 (pk1, pk2)) engine=myisam; insert into t3 values (1, 1); +--echo # Switching to connection 'blocker' connection blocker; # This will implicitly lock t3 for update and t2 for read, # since cascading change to t3 affects t3.fk2 and thus new # value of foreign key should be checked. lock table t1 write; +--echo # Switching to connection 'default' connection default; --send insert into t2 values (2, 2) +--echo # Switching to connection 'blocker' connection blocker; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Table lock" and info = "insert into t2 values (2, 2)"; --source include/wait_condition.inc unlock tables; +--echo # Switching to connection 'default' connection default; --reap drop tables t1, t2, t3; @@ -154,14 +184,18 @@ create table t2 (pk int primary key, insert into t2 values (1, 1); create table t3 (fk int references t2 (pk) on delete cascade) engine=myisam; insert into t3 values (1); +--echo # Switching to connection 'blocker' connection blocker; lock table t3 read; +--echo # Switching to connection 'default' connection default; # Should not be blocked since we are not updating t2.pk and # thus should not do any checks/actions to t3. delete from t1 where pk= 1; +--echo # Switching to connection 'blocker' connection blocker; unlock tables; +--echo # Switching to connection 'default' connection default; drop tables t1, t2, t3; create table t1 (pk int primary key) engine=myisam; @@ -173,18 +207,22 @@ create table t3 (fk1 int, fk2 int, foreign key (fk1, fk2) references t2 (pk1, pk2_fk) on update set null) engine=myisam; insert into t3 values (1, 1); +--echo # Switching to connection 'blocker' connection blocker; lock table t3 read; +--echo # Switching to connection 'default' connection default; # Should be blocked since we implicitly change primary # key in t2 and thus should update t3. --send update t1 set pk= 2 +--echo # Switching to connection 'blocker' connection blocker; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Table lock" and info = "update t1 set pk= 2"; --source include/wait_condition.inc unlock tables; +--echo # Switching to connection 'default' connection default; --reap drop tables t1, t2, t3; @@ -199,30 +237,38 @@ insert into t2 values (1, 1), (2, 2); create table t3 (fk int references t2 (pk) on update set null) engine=myisam; insert into t3 values (1), (2); create trigger t2_bu before update on t2 for each row set @a:= 1; +--echo # Switching to connection 'blocker' connection blocker; lock table t3 read; +--echo # Switching to connection 'default' connection default; # Should not be blocked since trigger on t2 doesn't change its # primary key and therefore t3 won't be updated. delete from t1 where pk=1; +--echo # Switching to connection 'blocker' connection blocker; unlock tables; +--echo # Switching to connection 'default' connection default; # Now scenario in which we should block drop trigger t2_bu; create trigger t2_bu before update on t2 for each row set new.pk=3; +--echo # Switching to connection 'blocker' connection blocker; lock table t3 read; +--echo # Switching to connection 'default' connection default; # Should be blocked since trigger on t2 will change its primary key # and therefore t3 should be updated. --send delete from t1 where pk=2 +--echo # Switching to connection 'blocker' connection blocker; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Table lock" and info = "delete from t1 where pk=2"; --source include/wait_condition.inc unlock tables; +--echo # Switching to connection 'default' connection default; --reap drop tables t1, t2, t3; === modified file 'sql/fk_dd.cc' --- a/sql/fk_dd.cc 2008-08-03 10:13:01 +0000 +++ b/sql/fk_dd.cc 2008-08-06 08:09:35 +0000 @@ -21,7 +21,7 @@ /* Sizes of various fields in .FRM section describing all foreign keys. */ -const uint FK_FRM_FKS_SECTION_LENGTH_SIZE= 2; +const uint FK_FRM_FKS_LIST_LENGTH_SIZE= 2; /* Sizes of fields constituting desrciption of individual FK. */ const uint FK_FRM_FK_DESCR_LENGTH_SIZE= 2; @@ -42,8 +42,8 @@ const uint FK_FRM_NAMES_SEP_SIZE= 1; uint Foreign_key_parent::get_frm_description_length() { - List_iterator col_it1(columns); - List_iterator col_it2(ref_columns); + List_iterator col_it1(child_columns); + List_iterator col_it2(parent_columns); const Key_part_spec *col; uint length= 0; @@ -101,7 +101,7 @@ uint Foreign_key_parent::get_additional_ which is specific for child table. */ -uint Foreign_key::get_additional_fixed_part_length() +uint Foreign_key_child::get_additional_fixed_part_length() { return FK_FRM_MATCH_OPT_SIZE; } @@ -116,14 +116,14 @@ uint Foreign_key::get_additional_fixed_p @return Length of foreign key section in .FRM file in bytes. */ -uint fk_get_frm_section_length(List &fkey_list, +uint fk_get_frm_section_length(List &fkey_list, List &parent_fkey_list) { - List_iterator fkey_iterator(fkey_list); + List_iterator fkey_iterator(fkey_list); List_iterator fkey_p_iterator(parent_fkey_list); - Foreign_key *fkey; + Foreign_key_child *fkey; Foreign_key_parent *fkey_p; - uint length= 2*FK_FRM_FKS_SECTION_LENGTH_SIZE; + uint length= 2*FK_FRM_FKS_LIST_LENGTH_SIZE; while ((fkey= fkey_iterator++)) length+= fkey->get_frm_description_length(); @@ -147,14 +147,14 @@ static const char FK_FRM_FLAG_WITHIN_ONE on leaving it will point to the position right after this description. - @note This function will use Foreign_key::get_frm_description_length() + @note This function will use Foreign_key_child::get_frm_description_length() bytes of buffer space. */ void Foreign_key_parent::save_to_frm(char **buff_p) { - List_iterator col_it1(columns); - List_iterator col_it2(ref_columns); + List_iterator col_it1(child_columns); + List_iterator col_it2(parent_columns); const Key_part_spec *col; char *fk_len_pos; char *cur_pos= *buff_p; @@ -179,7 +179,7 @@ void Foreign_key_parent::save_to_frm(cha *cur_pos= delete_opt; cur_pos+= FK_FRM_ON_DELETE_OPT_SIZE; save_additional_fixed_part(&cur_pos); - int2store(cur_pos, columns.elements); + int2store(cur_pos, child_columns.elements); cur_pos+= FK_FRM_NUM_COLUMNS_SIZE; /* Here we will store length of names & columns section later. */ @@ -261,7 +261,7 @@ void Foreign_key_parent::save_additional TABLE_LIST* Foreign_key_parent::get_table_for_frm() { - return table; + return child_table; } @@ -270,7 +270,7 @@ TABLE_LIST* Foreign_key_parent::get_tabl description in child table. */ -char Foreign_key::get_additional_flags() +char Foreign_key_child::get_additional_flags() { return is_table_constraint ? FK_FRM_FLAG_TABLE_CONSTRAINT : 0; } @@ -281,7 +281,7 @@ char Foreign_key::get_additional_flags() description of foreign key in .FRM. */ -void Foreign_key::save_additional_fixed_part(char **buff_p) +void Foreign_key_child::save_additional_fixed_part(char **buff_p) { /* Ensure that we are not saving non-fully-initialized object into .FRM. */ DBUG_ASSERT(match_opt != FK_MATCH_UNDEF); @@ -295,9 +295,9 @@ void Foreign_key::save_additional_fixed_ of foreign key in child table. */ -TABLE_LIST* Foreign_key::get_table_for_frm() +TABLE_LIST* Foreign_key_child::get_table_for_frm() { - return ref_table; + return parent_table; } @@ -308,53 +308,62 @@ TABLE_LIST* Foreign_key::get_table_for_f @param file Descriptor of open .FRM file. @param fkey_list List of foreign keys for which this table is child. @param parent_fkey_list List of foreign keys for which this table is parent. - @param predicted_length Length of the descriptions which was predicted - by fk_get_frm_section_length() function. + @param total_length Length of the descriptions which was given by + fk_get_frm_section_length() function. @retval TRUE in case of error. @retval FALSE otherwise. */ bool fk_save_to_frm_section(THD *thd, File file, - List &fkey_list, + List &fkey_list, List &parent_fkey_list, - uint predicted_length) + uint total_length) { - List_iterator fkey_iterator(fkey_list); + List_iterator fkey_iterator(fkey_list); List_iterator fkey_p_iterator(parent_fkey_list); - char *buff= (char *)thd->alloc(predicted_length); + char *buff= (char *)thd->alloc(total_length); char *cur_pos= buff; char *sec_pos; - Foreign_key *fkey; + Foreign_key_child *fkey; Foreign_key_parent *fkey_p; /* Check for OOM. */ if (!buff) return TRUE; - /* Save descriptions of foreign keys in which this table is child. */ + /* + Save descriptions of foreign keys in which this table is child. + + First reserve space where later we will store total length of descriptions + of these foreign keys. + */ sec_pos= cur_pos; - cur_pos+= FK_FRM_FKS_SECTION_LENGTH_SIZE; + cur_pos+= FK_FRM_FKS_LIST_LENGTH_SIZE; while ((fkey= fkey_iterator++)) { - DBUG_ASSERT(cur_pos < buff + predicted_length); + DBUG_ASSERT(cur_pos < buff + total_length); fkey->save_to_frm(&cur_pos); } - int2store(sec_pos, cur_pos - (sec_pos + FK_FRM_FKS_SECTION_LENGTH_SIZE)); + int2store(sec_pos, cur_pos - (sec_pos + FK_FRM_FKS_LIST_LENGTH_SIZE)); + + /* + Save descriptions of foreign keys in which this table is parent. - /* Save descriptions of foreign keys in which this table is parent. */ + Again as first step we reserve space for total length of those descriptions. + */ sec_pos= cur_pos; - cur_pos+= FK_FRM_FKS_SECTION_LENGTH_SIZE; + cur_pos+= FK_FRM_FKS_LIST_LENGTH_SIZE; while ((fkey_p= fkey_p_iterator++)) { - DBUG_ASSERT(cur_pos < buff + predicted_length); + DBUG_ASSERT(cur_pos < buff + total_length); fkey_p->save_to_frm(&cur_pos); } - int2store(sec_pos, cur_pos - (sec_pos + FK_FRM_FKS_SECTION_LENGTH_SIZE)); + int2store(sec_pos, cur_pos - (sec_pos + FK_FRM_FKS_LIST_LENGTH_SIZE)); - DBUG_ASSERT(cur_pos == buff + predicted_length); + DBUG_ASSERT(cur_pos == buff + total_length); - return my_write(file, (const uchar*)buff, predicted_length, MYF(MY_NABP)); + return my_write(file, (const uchar*)buff, total_length, MYF(MY_NABP)); } @@ -394,9 +403,9 @@ bool Foreign_key_share::restore_from_frm is_within_one_db= (*cur_pos) & FK_FRM_FLAG_WITHIN_ONE_DATABASE; restore_additional_flags(*cur_pos); cur_pos+= FK_FRM_FLAGS_SIZE; - update_opt= (fk_option)*cur_pos; + update_opt= (enum_fk_option)*cur_pos; cur_pos+= FK_FRM_ON_UPDATE_OPT_SIZE; - delete_opt= (fk_option)*cur_pos; + delete_opt= (enum_fk_option)*cur_pos; cur_pos+= FK_FRM_ON_DELETE_OPT_SIZE; /* Read part of fixed header which is specific for child or parent. */ @@ -433,13 +442,13 @@ bool Foreign_key_share::restore_from_frm { col_str_arr[i].str= (char *)names_cols_arr[3+i]; col_str_arr[i].length= names_cols_lengths[3+i]; - columns.push_back(&col_str_arr[i], &share->mem_root); + child_columns.push_back(&col_str_arr[i], &share->mem_root); } for (i= 0; i< col_number; i++) { col_str_arr[col_number+i].str= (char *)names_cols_arr[3+col_number+i]; col_str_arr[col_number+i].length= names_cols_lengths[3+col_number+i]; - ref_columns.push_back(&col_str_arr[col_number+i], &share->mem_root); + parent_columns.push_back(&col_str_arr[col_number+i], &share->mem_root); } /* Check for OOM .*/ @@ -484,7 +493,7 @@ void Foreign_key_child_share::restore_ad void Foreign_key_child_share::restore_from_additional_fixed_part(const char **buff_p) { - match_opt= (fk_match_opt) **buff_p; + match_opt= (enum_fk_match_opt) **buff_p; *buff_p+= FK_FRM_MATCH_OPT_SIZE; } @@ -553,12 +562,12 @@ bool fk_restore_from_frm_section(THD *th { uint section_length; - if (*buff_p + 2 * FK_FRM_FKS_SECTION_LENGTH_SIZE >= buff_end) + if (*buff_p + 2 * FK_FRM_FKS_LIST_LENGTH_SIZE >= buff_end) return FALSE; /* Restore foreign keys for which this table is child. */ section_length= uint2korr(*buff_p); - (*buff_p)+= FK_FRM_FKS_SECTION_LENGTH_SIZE; + (*buff_p)+= FK_FRM_FKS_LIST_LENGTH_SIZE; buff_end= *buff_p + section_length; @@ -574,7 +583,7 @@ bool fk_restore_from_frm_section(THD *th /* Restore foreign keys for which this table is parent. */ section_length= uint2korr(*buff_p); - (*buff_p)+= FK_FRM_FKS_SECTION_LENGTH_SIZE; + (*buff_p)+= FK_FRM_FKS_LIST_LENGTH_SIZE; buff_end= *buff_p + section_length; @@ -593,8 +602,7 @@ bool fk_restore_from_frm_section(THD *th /** - Names of referential actions in order corresponding to - Foreign_key::fk_option enum. + Names of referential actions in order corresponding to enum_fk_option enum. */ const LEX_STRING fk_ref_action_names[]= { {NULL, 0}, @@ -605,8 +613,7 @@ const LEX_STRING fk_ref_action_names[]= C_STRING_WITH_LEN("SET DEFAULT")}; /** - Names of match options in order corresponding to - Foreign_key::fk_match_opt enum. + Names of match options in order corresponding to enum_fk_match_opt enum. @note Contains NONE for MATCH SIMPLE as it is value which is show for this match option in I_S table. @@ -627,7 +634,7 @@ const LEX_STRING fk_match_type_names[]= void Foreign_key_child_share::get_create_statement_clause(THD *thd, String *str) { - List_iterator col_it1(columns), col_it2(ref_columns); + List_iterator col_it1(child_columns), col_it2(parent_columns); LEX_STRING *col; bool first; @@ -718,7 +725,7 @@ void fk_get_column_constraint_for_create { if (!fkey->is_table_constraint && !my_strcasecmp(system_charset_info, field_name, - fkey->columns.head()->str)) + fkey->child_columns.head()->str)) { fkey->get_create_statement_clause(thd, str); continue; @@ -753,7 +760,8 @@ void fk_get_table_constraints_for_create @param table_name Name of the table to be created/altered. */ -void Foreign_key::generate_name_if_needed(THD *thd, const char *table_name) +void Foreign_key_child::generate_name_if_needed(THD *thd, + const char *table_name) { if (!name.str || is_name_generated) { @@ -823,10 +831,10 @@ void Foreign_key::generate_name_if_neede */ void fk_generate_constraint_names(THD *thd, const char *table_name, - List &fkey_list) + List &fkey_list) { - List_iterator fkey_iterator(fkey_list); - Foreign_key *fkey; + List_iterator fkey_iterator(fkey_list); + Foreign_key_child *fkey; while ((fkey= fkey_iterator++)) fkey->generate_name_if_needed(thd, table_name); @@ -935,10 +943,11 @@ static bool fk_create_constraint_name(co @retval TRUE Error. */ -bool fk_create_constraint_names(List &fkey_list, const char *db) +bool fk_create_constraint_names(List &fkey_list, + const char *db) { - List_iterator fkey_iterator(fkey_list); - Foreign_key *fkey, *fkey_err; + List_iterator fkey_iterator(fkey_list); + Foreign_key_child *fkey, *fkey_err; while ((fkey= fkey_iterator++)) { @@ -1042,11 +1051,11 @@ bool fk_drop_all_constraint_names_for_ta @retval TRUE Some error discovered. */ -bool fk_check_constraint_added(THD *thd, Foreign_key *fkey, - List &fkey_list) +bool fk_check_constraint_added(THD *thd, Foreign_key_child *fkey, + List &fkey_list) { - List_iterator fkey_it2(fkey_list); - Foreign_key *fkey2; + List_iterator fkey_it2(fkey_list); + Foreign_key_child *fkey2; DBUG_ENTER("fk_check_constraint_added"); @@ -1064,16 +1073,16 @@ bool fk_check_constraint_added(THD *thd, DBUG_RETURN(TRUE); } - if (!fkey->ref_columns.elements) + if (!fkey->parent_columns.elements) { my_error(ER_FK_PARENT_COLUMN_MANDATORY, MYF(0), fkey->name.str); DBUG_RETURN(TRUE); } - if (fkey->ref_columns.elements != fkey->columns.elements) + if (fkey->parent_columns.elements != fkey->child_columns.elements) { my_error(ER_FK_PARENT_COLUMN_COUNT, MYF(0), fkey->name.str, - fkey->ref_columns.elements, fkey->columns.elements); + fkey->parent_columns.elements, fkey->child_columns.elements); DBUG_RETURN(TRUE); } @@ -1112,7 +1121,7 @@ bool fk_check_constraint_added(THD *thd, my_error(ER_FK_CONSTRAINT_NAME_ILLEGAL, MYF(0), fkey->name.str); DBUG_RETURN(TRUE); } - if (fk_check_if_constraint_name_exists(fkey->table->db, fkey->name.str)) + if (fk_check_if_constraint_name_exists(fkey->child_table->db, fkey->name.str)) { my_error(ER_FK_CONSTRAINT_NAME_DUPLICATE, MYF(0), fkey->name.str); DBUG_RETURN(TRUE); @@ -1189,67 +1198,70 @@ static bool fk_colnames_to_key_part_spec Foreign_key_parent* Foreign_key_parent_share::make_foreign_key(MEM_ROOT *mem_root) { - List cols, ref_cols; - TABLE_LIST *table; + List child_cols, parent_cols; + TABLE_LIST *child_tab; - if (fk_colnames_to_key_part_spec(columns, &cols, mem_root) || - fk_colnames_to_key_part_spec(ref_columns, &ref_cols, mem_root)) + if (fk_colnames_to_key_part_spec(child_columns, &child_cols, mem_root) || + fk_colnames_to_key_part_spec(parent_columns, &parent_cols, mem_root)) return NULL; - if (!(table= (TABLE_LIST*)alloc_root(mem_root, sizeof(TABLE_LIST)))) + if (!(child_tab= (TABLE_LIST*)alloc_root(mem_root, sizeof(TABLE_LIST)))) return NULL; - bzero(table, sizeof(TABLE_LIST)); - table->db= child_table_db.str; - table->db_length= child_table_db.length; - table->table_name= child_table_name.str; - table->table_name_length= child_table_name.length; + bzero(child_tab, sizeof(TABLE_LIST)); + child_tab->db= child_table_db.str; + child_tab->db_length= child_table_db.length; + child_tab->table_name= child_table_name.str; + child_tab->table_name_length= child_table_name.length; - return new (mem_root) Foreign_key_parent(name, table, cols, ref_cols, - delete_opt, update_opt, + return new (mem_root) Foreign_key_parent(name, child_tab, child_cols, + parent_cols, delete_opt, update_opt, is_within_one_db); } /** Given object representing foreign key in the share of child table - create Foreign_key instance describing it, which can be used for - saving information about this foreign key into .FRM during ALTER - TABLE. + create Foreign_key_child instance describing it, which can be used + for saving information about this foreign key into .FRM during + ALTER TABLE. - @param mem_root Memory root to be used for allocating new object. + @param mem_root Memory root to be used for allocating new object. + @param child_tab Table list element for child table. @note Since created object will contain references to the memory and members of original object its life-time is limited by lifetime of the original object. - @retval non-NULL Pointer to new Foreign_key instance. + @retval non-NULL Pointer to new Foreign_key_child instance. @retval NULL OOM occurred. */ -Foreign_key* -Foreign_key_child_share::make_foreign_key(MEM_ROOT *mem_root, TABLE_LIST *table) +Foreign_key_child* +Foreign_key_child_share::make_foreign_key(MEM_ROOT *mem_root, + TABLE_LIST *child_tab) { - List cols, ref_cols; - TABLE_LIST *ref_table; + List child_cols, parent_cols; + TABLE_LIST *parent_tab; - if (fk_colnames_to_key_part_spec(columns, &cols, mem_root) || - fk_colnames_to_key_part_spec(ref_columns, &ref_cols, mem_root)) + if (fk_colnames_to_key_part_spec(child_columns, &child_cols, mem_root) || + fk_colnames_to_key_part_spec(parent_columns, &parent_cols, mem_root)) return NULL; - if (!(ref_table= (TABLE_LIST*)alloc_root(mem_root, sizeof(TABLE_LIST)))) + if (!(parent_tab= (TABLE_LIST*)alloc_root(mem_root, sizeof(TABLE_LIST)))) return NULL; - bzero(ref_table, sizeof(TABLE_LIST)); - ref_table->db= parent_table_db.str; - ref_table->db_length= parent_table_db.length; - ref_table->table_name= parent_table_name.str; - ref_table->table_name_length= parent_table_name.length; - - return new (mem_root) Foreign_key(name, null_lex_str, is_table_constraint, - table, cols, ref_table, ref_cols, - delete_opt, update_opt, match_opt, - is_within_one_db, TRUE); + bzero(parent_tab, sizeof(TABLE_LIST)); + parent_tab->db= parent_table_db.str; + parent_tab->db_length= parent_table_db.length; + parent_tab->table_name= parent_table_name.str; + parent_tab->table_name_length= parent_table_name.length; + + return new (mem_root) Foreign_key_child(name, null_lex_str, + is_table_constraint, + child_tab, child_cols, parent_tab, + parent_cols, delete_opt, update_opt, + match_opt, is_within_one_db, TRUE); } @@ -1314,7 +1326,7 @@ bool Foreign_key_share::init_column_set( List& Foreign_key_child_share::get_table_columns() { - return columns; + return child_columns; } @@ -1327,7 +1339,7 @@ List& Foreign_key_child_shar List& Foreign_key_parent_share::get_table_columns() { - return ref_columns; + return parent_columns; } @@ -1568,7 +1580,7 @@ bool fk_add_tables_for_fks(THD *thd, LEX if (fk_add_table_to_table_list(thd, lex, fk->child_table_db, fk->child_table_name, TL_WRITE, static_cast(1 << static_cast(TRG_EVENT_UPDATE)), - table->belong_to_view, &fk->columns)) + table->belong_to_view, &fk->child_columns)) return TRUE; } else @@ -1606,7 +1618,7 @@ bool fk_add_tables_for_fks(THD *thd, LEX if (fk_add_table_to_table_list(thd, lex, fk->child_table_db, fk->child_table_name, TL_WRITE, static_cast(1 << static_cast(TRG_EVENT_UPDATE)), - table->belong_to_view, &fk->columns)) + table->belong_to_view, &fk->child_columns)) return TRUE; } } === modified file 'sql/fk_dd.h' --- a/sql/fk_dd.h 2008-08-03 10:13:01 +0000 +++ b/sql/fk_dd.h 2008-08-06 08:09:35 +0000 @@ -16,9 +16,10 @@ #ifndef SQL_FK_H #define SQL_FK_H -uint fk_get_frm_section_length(List &fkey_list, +uint fk_get_frm_section_length(List &fkey_list, List &parent_fkey_list); -bool fk_save_to_frm_section(THD *thd, File file, List &fkey_list, +bool fk_save_to_frm_section(THD *thd, File file, + List &fkey_list, List &parent_fkey_list, uint predicted_length); bool fk_restore_from_frm_section(THD *thd, TABLE_SHARE *share, @@ -33,15 +34,16 @@ void fk_get_column_constraint_for_create void fk_generate_constraint_names(THD *thd, const char *table_name, - List &fkey_list); + List &fkey_list); bool fk_check_if_constraint_name_exists(const char *db, const char *name); -bool fk_create_constraint_names(List &fkey_list, const char *db); +bool fk_create_constraint_names(List &fkey_list, + const char *db); bool fk_drop_constraint_name(const char *db, const char *name); bool fk_drop_all_constraint_names_for_table(THD *thd, TABLE_LIST *table); -bool fk_check_constraint_added(THD *thd, Foreign_key *fkey, - List &fkey_list); +bool fk_check_constraint_added(THD *thd, Foreign_key_child *fkey, + List &fkey_list); bool fk_init_column_sets(TABLE_SHARE *share); === modified file 'sql/mysql_priv.h' --- a/sql/mysql_priv.h 2008-08-03 10:13:01 +0000 +++ b/sql/mysql_priv.h 2008-08-06 08:09:35 +0000 @@ -2197,7 +2197,7 @@ bool mysql_create_frm(THD *thd, const ch HA_CREATE_INFO *create_info, List &create_field, uint key_count,KEY *key_info, - List &fkey_list, + List &fkey_list, List &parent_fkey_list, handler *db_type); int rea_create_table(THD *thd, const char *path, @@ -2205,7 +2205,7 @@ int rea_create_table(THD *thd, const cha HA_CREATE_INFO *create_info, List &create_field, uint key_count,KEY *key_info, - List &fkey_list, + List &fkey_list, List &parent_fkey_list, handler *file); int format_number(uint inputflag,uint max_length,char * pos,uint length, === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2008-08-03 10:13:01 +0000 +++ b/sql/sql_class.cc 2008-08-06 08:09:35 +0000 @@ -123,29 +123,30 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_r Foreign_key_parent::Foreign_key_parent(const Foreign_key_parent &rhs, MEM_ROOT *mem_root) : name(rhs.name), - columns(rhs.columns, mem_root), - table(rhs.table), - ref_columns(rhs.ref_columns, mem_root), + child_columns(rhs.child_columns, mem_root), + child_table(rhs.child_table), + parent_columns(rhs.parent_columns, mem_root), delete_opt(rhs.delete_opt), update_opt(rhs.update_opt), is_within_one_db(rhs.is_within_one_db) { - list_copy_and_replace_each_value(columns, mem_root); - list_copy_and_replace_each_value(ref_columns, mem_root); + list_copy_and_replace_each_value(child_columns, mem_root); + list_copy_and_replace_each_value(parent_columns, mem_root); } /** - Construct an (almost) deep copy of this foreign key. Only those - elements that are known to never change are not copied. + Construct an (almost) deep copy of Foreign_key_child object. + Only those elements that are known to never change are not copied. If out of memory, a partial copy is returned and an error is set in THD. */ -Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root) +Foreign_key_child::Foreign_key_child(const Foreign_key_child &rhs, + MEM_ROOT *mem_root) : Foreign_key_parent(rhs, mem_root), - ref_table(rhs.ref_table), + parent_table(rhs.parent_table), match_opt(rhs.match_opt), fkey_clause_name(rhs.fkey_clause_name), is_table_constraint(rhs.is_table_constraint), === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2008-08-03 10:13:01 +0000 +++ b/sql/sql_class.h 2008-08-06 08:09:35 +0000 @@ -237,10 +237,11 @@ public: }; -enum fk_match_opt { FK_MATCH_UNDEF, FK_MATCH_FULL, - FK_MATCH_PARTIAL, FK_MATCH_SIMPLE}; -enum fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, FK_OPTION_CASCADE, - FK_OPTION_SET_NULL, FK_OPTION_NO_ACTION, FK_OPTION_DEFAULT}; +enum enum_fk_match_opt { FK_MATCH_UNDEF, FK_MATCH_FULL, + FK_MATCH_PARTIAL, FK_MATCH_SIMPLE}; +enum enum_fk_option { FK_OPTION_UNDEF, FK_OPTION_RESTRICT, + FK_OPTION_CASCADE, FK_OPTION_SET_NULL, + FK_OPTION_NO_ACTION, FK_OPTION_DEFAULT}; /** @@ -253,10 +254,10 @@ enum fk_option { FK_OPTION_UNDEF, FK_OPT class Foreign_key_parent: public Sql_alloc { public: LEX_STRING name; - List columns; - TABLE_LIST *table; - List ref_columns; - fk_option delete_opt, update_opt; + List child_columns; + TABLE_LIST *child_table; + List parent_columns; + enum_fk_option delete_opt, update_opt; /** Indicates whether child and parent table of foreign key are in the same database. @@ -264,12 +265,14 @@ public: bool is_within_one_db; Foreign_key_parent(const LEX_STRING &name_arg, - TABLE_LIST *tab, const List &cols, - const List &ref_cols, - fk_option delete_opt_arg, - fk_option update_opt_arg, + TABLE_LIST *child_tab_arg, + const List &child_cols_arg, + const List &parent_cols_arg, + enum_fk_option delete_opt_arg, + enum_fk_option update_opt_arg, bool within_one_db_arg) - : name(name_arg), columns(cols), table(tab), ref_columns(ref_cols), + : name(name_arg), child_columns(child_cols_arg), + child_table(child_tab_arg), parent_columns(parent_cols_arg), delete_opt(delete_opt_arg), update_opt(update_opt_arg), is_within_one_db(within_one_db_arg) {} @@ -301,10 +304,10 @@ protected: in .FRM file of its child table). */ -class Foreign_key: public Foreign_key_parent { +class Foreign_key_child: public Foreign_key_parent { public: - TABLE_LIST *ref_table; - fk_match_opt match_opt; + TABLE_LIST *parent_table; + enum_fk_match_opt match_opt; /** Name of foreign key which was specified in non-standard way in FOREIGN KEY clause. @@ -328,24 +331,27 @@ public: */ bool exists; - Foreign_key(const LEX_STRING &name_arg, - const LEX_STRING &fkey_clause_name_arg, - bool table_con_arg, - TABLE_LIST *tab, const List &cols, - TABLE_LIST *ref_tab, const List &ref_cols, - fk_option delete_opt_arg, fk_option update_opt_arg, - fk_match_opt match_opt_arg, bool within_one_db_arg, - bool exists_arg) - : Foreign_key_parent(name_arg, tab, cols, ref_cols, delete_opt_arg, + Foreign_key_child(const LEX_STRING &name_arg, + const LEX_STRING &fkey_clause_name_arg, + bool table_con_arg, TABLE_LIST *child_tab_arg, + const List &child_cols_arg, + TABLE_LIST *parent_tab_arg, + const List &parent_cols_arg, + enum_fk_option delete_opt_arg, + enum_fk_option update_opt_arg, + enum_fk_match_opt match_opt_arg, + bool within_one_db_arg, bool exists_arg) + : Foreign_key_parent(name_arg, child_tab_arg, child_cols_arg, + parent_cols_arg, delete_opt_arg, update_opt_arg, within_one_db_arg), - ref_table(ref_tab), match_opt(match_opt_arg), + parent_table(parent_tab_arg), match_opt(match_opt_arg), fkey_clause_name(fkey_clause_name_arg), is_table_constraint(table_con_arg), is_name_generated(FALSE), exists(exists_arg) {} - Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root); - Foreign_key *clone(MEM_ROOT *mem_root) const - { return new (mem_root) Foreign_key(*this, mem_root); } + Foreign_key_child(const Foreign_key_child &rhs, MEM_ROOT *mem_root); + Foreign_key_child *clone(MEM_ROOT *mem_root) const + { return new (mem_root) Foreign_key_child(*this, mem_root); } /** If needed set values for MATCH and ON UPDATE/DELETE clauses @@ -361,7 +367,7 @@ public: if (delete_opt == FK_OPTION_UNDEF) delete_opt= FK_OPTION_NO_ACTION; - if (!strcmp(table->db, ref_table->db)) + if (!strcmp(child_table->db, parent_table->db)) is_within_one_db= TRUE; } @@ -383,9 +389,9 @@ class Foreign_key_share: public Sql_allo { public: LEX_STRING name; - List columns; - List ref_columns; - fk_option delete_opt, update_opt; + List child_columns; + List parent_columns; + enum_fk_option delete_opt, update_opt; bool is_within_one_db; /** Set of columns in the table participating in foreign key. @@ -421,12 +427,12 @@ class Foreign_key_child_share: public Fo public: LEX_STRING parent_table_db; LEX_STRING parent_table_name; - fk_match_opt match_opt; + enum_fk_match_opt match_opt; bool is_table_constraint; void get_create_statement_clause(THD *thd, String *str); - Foreign_key *make_foreign_key(MEM_ROOT *mem_root, TABLE_LIST *table); + Foreign_key_child *make_foreign_key(MEM_ROOT *mem_root, TABLE_LIST *table); protected: virtual void restore_additional_flags(char flags); === modified file 'sql/sql_lex.h' --- a/sql/sql_lex.h 2008-08-03 10:13:01 +0000 +++ b/sql/sql_lex.h 2008-08-06 08:09:35 +0000 @@ -882,7 +882,7 @@ public: List drop_list; List alter_list; List key_list; - List foreign_key_list; + List foreign_key_list; List parent_foreign_key_list; List create_list; uint flags; @@ -1645,9 +1645,9 @@ typedef struct st_lex : public Query_tab enum ha_storage_media storage_type; enum column_format_type column_format; uint grant, grant_tot_col, which_columns; - enum fk_match_opt fk_match_option; - enum fk_option fk_update_opt; - enum fk_option fk_delete_opt; + enum enum_fk_match_opt fk_match_option; + enum enum_fk_option fk_update_opt; + enum enum_fk_option fk_delete_opt; uint slave_thd_opt, start_transaction_opt; int nest_level; /* === modified file 'sql/sql_show.cc' --- a/sql/sql_show.cc 2008-08-03 10:13:01 +0000 +++ b/sql/sql_show.cc 2008-08-06 08:09:35 +0000 @@ -4990,7 +4990,8 @@ static int get_schema_key_column_usage_r Foreign_key_child_share *fkey; while ((fkey= fk_it++)) { - List_iterator it(fkey->columns), it1(fkey->ref_columns); + List_iterator it(fkey->child_columns), + it1(fkey->parent_columns); LEX_STRING *f_col, *r_col; uint f_idx= 0; === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2008-08-03 10:13:01 +0000 +++ b/sql/sql_table.cc 2008-08-06 08:09:35 +0000 @@ -2604,11 +2604,11 @@ mysql_prepare_create_table(THD *thd, List_iterator key_iterator(alter_info->key_list); List_iterator key_iterator2(alter_info->key_list); - List_iterator fkey_it(alter_info->foreign_key_list); + List_iterator fkey_it(alter_info->foreign_key_list); uint key_parts=0, fk_key_count=0; bool primary_key=0,unique_key=0; Key *key, *key2; - Foreign_key *fkey; + Foreign_key_child *fkey; uint tmp, key_number; /* special marker for keys to be ignored */ static char ignore_key[1]; @@ -2630,8 +2630,8 @@ mysql_prepare_create_table(THD *thd, } else { - if (fkey->ref_columns.elements && - fkey->ref_columns.elements != fkey->columns.elements) + if (fkey->parent_columns.elements && + fkey->parent_columns.elements != fkey->child_columns.elements) { my_error(ER_WRONG_FK_DEF, MYF(0), fkey->name.str ? fkey->name.str : "foreign key without name", @@ -2647,7 +2647,7 @@ mysql_prepare_create_table(THD *thd, { key= new (thd->mem_root) Key(Key::MULTIPLE, fkey->name, &default_key_create_info, 1, - fkey->columns); + fkey->child_columns); alter_info->key_list.push_back(key); } } @@ -3407,8 +3407,8 @@ bool mysql_create_table_no_lock(THD *thd Check that we don't use foreign keys in the table since it won't work even with InnoDB beneath it. */ - List_iterator fkey_it(alter_info->foreign_key_list); - Foreign_key *fkey; + List_iterator fkey_it(alter_info->foreign_key_list); + Foreign_key_child *fkey; handlerton *part_engine_type= create_info->db_type; char *part_syntax_buf; uint syntax_len; @@ -3798,7 +3798,7 @@ static bool lock_table_name_if_not_cache static bool create_frm_with_ref_fks(THD *thd, TABLE_LIST *table, char *dst_path, - List &fk_list) + List &fk_list) { HA_CREATE_INFO create_info; Alter_info alter_info; @@ -3814,8 +3814,8 @@ static bool create_frm_with_ref_fks(THD if (mysql_prepare_alter_table(thd, table, &create_info, &alter_info)) DBUG_RETURN(TRUE); - List_iterator fkey_it(fk_list); - Foreign_key *fkey; + List_iterator fkey_it(fk_list); + Foreign_key_child *fkey; Foreign_key_parent *fkey_p; /* @@ -3824,7 +3824,7 @@ static bool create_frm_with_ref_fks(THD */ while ((fkey= fkey_it++)) { - if (fkey->ref_table == table) + if (fkey->parent_table == table) { if (!(fkey_p= new (thd->mem_root) Foreign_key_parent(*fkey, thd->mem_root))) DBUG_RETURN(TRUE); @@ -3870,9 +3870,9 @@ static bool prepare_create_table_with_fk TABLE_LIST *fkey_tables, Alter_info *alter_info) { - List_iterator fkey_it(alter_info->foreign_key_list); + List_iterator fkey_it(alter_info->foreign_key_list); TABLE_LIST *tab; - Foreign_key *fkey; + Foreign_key_child *fkey; Foreign_key_parent *fkey_p; /* @@ -3896,7 +3896,7 @@ static bool prepare_create_table_with_fk */ while ((fkey= fkey_it++)) { - if (fkey->ref_table == create_table) + if (fkey->parent_table == create_table) { if (!(fkey_p= new (thd->mem_root) Foreign_key_parent(*fkey, thd->mem_root)) || @@ -6242,7 +6242,7 @@ mysql_prepare_alter_table(THD *thd, TABL /* New key definitions are added here */ List new_key_list; /* FKs definitions for new version of table are added here. */ - List new_foreign_key_list; + List new_foreign_key_list; List new_parent_foreign_key_list; List_iterator drop_it(alter_info->drop_list); List_iterator def_it(alter_info->create_list); @@ -6447,7 +6447,7 @@ mysql_prepare_alter_table(THD *thd, TABL List_iterator fk_p_it(table->s->fkeys_parent); Foreign_key_child_share *fk_c_s; Foreign_key_parent_share *fk_p_s; - Foreign_key *fk; + Foreign_key_child *fk; Foreign_key_parent *fk_p; while ((fk_c_s= fk_c_it++)) { === modified file 'sql/sql_yacc.yy' --- a/sql/sql_yacc.yy 2008-08-03 10:13:01 +0000 +++ b/sql/sql_yacc.yy 2008-08-06 08:09:35 +0000 @@ -580,7 +580,7 @@ bool setup_select_in_parentheses(LEX *le enum index_hint_type index_hint; enum enum_filetype filetype; enum ha_build_method build_method; - enum fk_option m_fk_option; + enum enum_fk_option m_fk_option; } %{ @@ -4752,7 +4752,7 @@ column_ref_constraint_def: { THD *thd= YYTHD; LEX *lex= thd->lex; - Foreign_key *key; + Foreign_key_child *key; TABLE_LIST *table; lex->col_list.push_back(new (thd->mem_root) Key_part_spec(lex->ident, 0)); @@ -4761,15 +4761,15 @@ column_ref_constraint_def: TL_OPTION_DONT_ADD_DUPS), TL_IGNORE))) YYABORT; - key= new (thd->mem_root) Foreign_key($1, null_lex_str, FALSE, - lex->query_tables, - lex->col_list, - table, - lex->ref_list, - lex->fk_delete_opt, - lex->fk_update_opt, - lex->fk_match_option, - FALSE, FALSE); + key= new (thd->mem_root) Foreign_key_child($1, null_lex_str, FALSE, + lex->query_tables, + lex->col_list, + table, + lex->ref_list, + lex->fk_delete_opt, + lex->fk_update_opt, + lex->fk_match_option, + FALSE, FALSE); key->set_missing_options(); lex->alter_info.foreign_key_list.push_back(key); /* Only used for ALTER TABLE. Ignored otherwise. */ @@ -4805,23 +4805,23 @@ key_def: { THD *thd= YYTHD; LEX *lex= thd->lex; - Foreign_key *key; + Foreign_key_child *key; TABLE_LIST *table; if (!(table= lex->select_lex.add_table_to_list(YYTHD, $8, NULL, (TL_OPTION_UPDATING | TL_OPTION_DONT_ADD_DUPS), TL_IGNORE))) YYABORT; - key= new (thd->mem_root) Foreign_key($1.str ? $1 : $4, $4, - TRUE, - lex->query_tables, - lex->col_list, - table, - lex->ref_list, - lex->fk_delete_opt, - lex->fk_update_opt, - lex->fk_match_option, - FALSE, FALSE); + key= new (thd->mem_root) Foreign_key_child($1.str ? $1 : $4, $4, + TRUE, + lex->query_tables, + lex->col_list, + table, + lex->ref_list, + lex->fk_delete_opt, + lex->fk_update_opt, + lex->fk_match_option, + FALSE, FALSE); key->set_missing_options(); lex->alter_info.foreign_key_list.push_back(key); lex->col_list.empty(); /* Alloced by sql_alloc */ === modified file 'sql/unireg.cc' --- a/sql/unireg.cc 2008-08-03 10:13:01 +0000 +++ b/sql/unireg.cc 2008-08-06 08:09:35 +0000 @@ -104,7 +104,7 @@ bool mysql_create_frm(THD *thd, const ch HA_CREATE_INFO *create_info, List &create_fields, uint keys, KEY *key_info, - List &fkey_list, + List &fkey_list, List &parent_fkey_list, handler *db_file) { @@ -486,7 +486,7 @@ int rea_create_table(THD *thd, const cha HA_CREATE_INFO *create_info, List &create_fields, uint keys, KEY *key_info, - List &fkey_list, + List &fkey_list, List &parent_fkey_list, handler *file) {