Commit d72c7984 authored by greg@mysql.com's avatar greg@mysql.com

Merge gweir@bk-internal.mysql.com:/home/bk/mysql-4.0

into mysql.com:/bk/mysql-4.0
parents 2f711c88 efb134f3
...@@ -37,6 +37,7 @@ EXTRA_DIST = FINISH.sh \ ...@@ -37,6 +37,7 @@ EXTRA_DIST = FINISH.sh \
compile-pentium-pgcc \ compile-pentium-pgcc \
compile-solaris-sparc \ compile-solaris-sparc \
compile-solaris-sparc-debug \ compile-solaris-sparc-debug \
compile-irix-mips64-mipspro \
compile-solaris-sparc-forte \ compile-solaris-sparc-forte \
compile-solaris-sparc-purify compile-solaris-sparc-purify
......
This diff is collapsed.
...@@ -348,7 +348,7 @@ AC_SUBST(CXXFLAGS) ...@@ -348,7 +348,7 @@ AC_SUBST(CXXFLAGS)
AC_SUBST(LD) AC_SUBST(LD)
AC_SUBST(INSTALL_SCRIPT) AC_SUBST(INSTALL_SCRIPT)
export CC CFLAGS LD LDFLAGS export CC CXX CFLAGS LD LDFLAGS AR
if test "$GXX" = "yes" if test "$GXX" = "yes"
then then
......
...@@ -1845,6 +1845,24 @@ dict_index_build_internal_non_clust( ...@@ -1845,6 +1845,24 @@ dict_index_build_internal_non_clust(
/*====================== FOREIGN KEY PROCESSING ========================*/ /*====================== FOREIGN KEY PROCESSING ========================*/
/*************************************************************************
Checks if a table is referenced by foreign keys. */
ibool
dict_table_referenced_by_foreign_key(
/*=================================*/
/* out: TRUE if table is referenced by a
foreign key */
dict_table_t* table) /* in: InnoDB table */
{
if (UT_LIST_GET_LEN(table->referenced_list) > 0) {
return(TRUE);
}
return(FALSE);
}
/************************************************************************* /*************************************************************************
Frees a foreign key struct. */ Frees a foreign key struct. */
static static
......
...@@ -206,6 +206,15 @@ dict_foreign_add_to_cache( ...@@ -206,6 +206,15 @@ dict_foreign_add_to_cache(
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
dict_foreign_t* foreign); /* in, own: foreign key constraint */ dict_foreign_t* foreign); /* in, own: foreign key constraint */
/************************************************************************* /*************************************************************************
Checks if a table is referenced by foreign keys. */
ibool
dict_table_referenced_by_foreign_key(
/*=================================*/
/* out: TRUE if table is referenced by a
foreign key */
dict_table_t* table); /* in: InnoDB table */
/*************************************************************************
Scans a table create SQL string and adds to the data dictionary Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function the foreign key constraints declared in the string. This function
should be called after the indexes for a table have been created. should be called after the indexes for a table have been created.
......
...@@ -1997,8 +1997,15 @@ row_drop_table_for_mysql( ...@@ -1997,8 +1997,15 @@ row_drop_table_for_mysql(
goto funct_exit; goto funct_exit;
} }
/* Check if the table is referenced by foreign key constraints from
some other table (not the table itself) */
foreign = UT_LIST_GET_FIRST(table->referenced_list); foreign = UT_LIST_GET_FIRST(table->referenced_list);
while (foreign && foreign->foreign_table == table) {
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
if (foreign && trx->check_foreigns) { if (foreign && trx->check_foreigns) {
char* buf = dict_foreign_err_buf; char* buf = dict_foreign_err_buf;
......
...@@ -4289,7 +4289,28 @@ ha_innobase::get_foreign_key_create_info(void) ...@@ -4289,7 +4289,28 @@ ha_innobase::get_foreign_key_create_info(void)
prebuilt->trx->op_info = (char*)""; prebuilt->trx->op_info = (char*)"";
return(str); return(str);
} }
/***********************************************************************
Checks if a table is referenced by a foreign key. The MySQL manual states that
a REPLACE is either equivalent to an INSERT, or DELETE(s) + INSERT. Only a
delete is then allowed internally to resolve a duplicate key conflict in
REPLACE, not an update. */
uint
ha_innobase::referenced_by_foreign_key(void)
/*========================================*/
/* out: > 0 if referenced by a FOREIGN KEY */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
if (dict_table_referenced_by_foreign_key(prebuilt->table)) {
return(1);
}
return(0);
}
/*********************************************************************** /***********************************************************************
Frees the foreign key create info for a table stored in InnoDB, if it is Frees the foreign key create info for a table stored in InnoDB, if it is
......
...@@ -179,6 +179,7 @@ class ha_innobase: public handler ...@@ -179,6 +179,7 @@ class ha_innobase: public handler
int check(THD* thd, HA_CHECK_OPT* check_opt); int check(THD* thd, HA_CHECK_OPT* check_opt);
char* update_table_comment(const char* comment); char* update_table_comment(const char* comment);
char* get_foreign_key_create_info(); char* get_foreign_key_create_info();
uint referenced_by_foreign_key();
void free_foreign_key_create_info(char* str); void free_foreign_key_create_info(char* str);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); enum thr_lock_type lock_type);
......
...@@ -319,6 +319,9 @@ class handler :public Sql_alloc ...@@ -319,6 +319,9 @@ class handler :public Sql_alloc
virtual void append_create_info(String *packet) {} virtual void append_create_info(String *packet) {}
virtual char* get_foreign_key_create_info() virtual char* get_foreign_key_create_info()
{ return(NULL);} /* gets foreign key create string from InnoDB */ { return(NULL);} /* gets foreign key create string from InnoDB */
/* used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
virtual uint referenced_by_foreign_key() { return 0;}
virtual void init_table_handle_for_HANDLER() virtual void init_table_handle_for_HANDLER()
{ return; } /* prepare InnoDB for HANDLER */ { return; } /* prepare InnoDB for HANDLER */
virtual void free_foreign_key_create_info(char* str) {} virtual void free_foreign_key_create_info(char* str) {}
......
...@@ -438,11 +438,20 @@ int write_record(TABLE *table,COPY_INFO *info) ...@@ -438,11 +438,20 @@ int write_record(TABLE *table,COPY_INFO *info)
key_copy((byte*) key,table,key_nr,0); key_copy((byte*) key,table,key_nr,0);
if ((error=(table->file->index_read_idx(table->record[1],key_nr, if ((error=(table->file->index_read_idx(table->record[1],key_nr,
(byte*) key, (byte*) key,
table->key_info[key_nr].key_length, table->key_info[key_nr].
key_length,
HA_READ_KEY_EXACT)))) HA_READ_KEY_EXACT))))
goto err; goto err;
} }
if (last_uniq_key(table,key_nr)) /*
The manual defines the REPLACE semantics that it is either an INSERT or
DELETE(s) + INSERT; FOREIGN KEY checks do not function in the defined
way if we allow MySQL to convert the latter operation internally to an
UPDATE.
*/
if (last_uniq_key(table,key_nr) &&
!table->file->referenced_by_foreign_key())
{ {
if ((error=table->file->update_row(table->record[1],table->record[0]))) if ((error=table->file->update_row(table->record[1],table->record[0])))
goto err; goto err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment