From 130740248b1eafcd935e7c75cfc2f195abb63a55 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sun, 4 Jul 2004 08:46:28 +0300 Subject: [PATCH 01/30] aggregate functions check during substitution made only for single row subselects (BUG#4400) restoring current senect pointer before PS rexecution (backport from 5.0) removed spaces at lines ends --- mysql-test/r/subselect.result | 8 +++++++ mysql-test/t/subselect.test | 10 ++++++++ sql/item_subselect.cc | 44 +++++++++++++++++------------------ sql/item_subselect.h | 10 ++++---- sql/sql_prepare.cc | 1 + 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 5ab36dacaaf..77339473142 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1891,3 +1891,11 @@ abc b 3 4 deallocate prepare stmt1; DROP TABLE t1, t2, t3; +CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1; +insert into t1 values (1); +CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1; +insert into t2 values (1,2); +select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1); +a C +1 1 +drop table t1,t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 0c093c4ae3e..eb4b1f33b14 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1212,3 +1212,13 @@ execute stmt1; select * from t3; deallocate prepare stmt1; DROP TABLE t1, t2, t3; + +# +# Aggregate function comparation with ALL/ANY/SOME subselect +# +CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1; +insert into t1 values (1); +CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1; +insert into t2 values (1,2); +select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1); +drop table t1,t2; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 4c1ffeecc97..ccc72cea608 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* +/* subselect Item SUBSELECT TODO: @@ -41,7 +41,7 @@ Item_subselect::Item_subselect(): { reset(); /* - item value is NULL if select_subselect not changed this value + item value is NULL if select_subselect not changed this value (i.e. some rows will be found returned) */ null_value= 1; @@ -114,7 +114,7 @@ Item_subselect::~Item_subselect() } Item_subselect::trans_res -Item_subselect::select_transformer(JOIN *join) +Item_subselect::select_transformer(JOIN *join) { DBUG_ENTER("Item_subselect::select_transformer"); DBUG_RETURN(RES_OK); @@ -148,11 +148,11 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) if (have_to_be_excluded) engine->exclude(); substitution= 0; - thd->where= "checking transformed subquery"; + thd->where= "checking transformed subquery"; if (!(*ref)->fixed) ret= (*ref)->fix_fields(thd, tables, ref); - // We can't substitute aggregate functions (like (SELECT (max(i))) - if ((*ref)->with_sum_func) + // We can't substitute aggregate functions like "SELECT (max(i))" + if (substype() == SINGLEROW_SUBS && (*ref)->with_sum_func) { my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0)); return 1; @@ -161,7 +161,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) } // Is it one field subselect? if (engine->cols() > max_columns) - { + { my_error(ER_OPERAND_COLUMNS, MYF(0), 1); return 1; } @@ -199,7 +199,7 @@ bool Item_subselect::exec() return (res); } -Item::Type Item_subselect::type() const +Item::Type Item_subselect::type() const { return SUBSELECT_ITEM; } @@ -277,7 +277,7 @@ Item_maxmin_subselect::Item_maxmin_subselect(Item_subselect *parent, */ used_tables_cache= parent->get_used_tables_cache(); const_item_cache= parent->get_const_item_cache(); - + DBUG_VOID_RETURN; } @@ -299,7 +299,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join) { if (changed) return RES_OK; - + SELECT_LEX *select_lex= join->select_lex; Statement backup; @@ -314,10 +314,10 @@ Item_singlerow_subselect::select_transformer(JOIN *join) TODO: solve above problem */ !(select_lex->item_list.head()->type() == FIELD_ITEM || - select_lex->item_list.head()->type() == REF_ITEM) + select_lex->item_list.head()->type() == REF_ITEM) ) { - + have_to_be_excluded= 1; if (join->thd->lex->describe) { @@ -355,7 +355,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join) return RES_REDUCE; } return RES_OK; - + err: if (stmt) thd->restore_backup_item_arena(stmt, &backup); @@ -418,7 +418,7 @@ void Item_singlerow_subselect::bring_value() exec(); } -double Item_singlerow_subselect::val() +double Item_singlerow_subselect::val() { DBUG_ASSERT(fixed == 1); if (!exec() && !value->null_value) @@ -433,7 +433,7 @@ double Item_singlerow_subselect::val() } } -longlong Item_singlerow_subselect::val_int() +longlong Item_singlerow_subselect::val_int() { DBUG_ASSERT(fixed == 1); if (!exec() && !value->null_value) @@ -448,7 +448,7 @@ longlong Item_singlerow_subselect::val_int() } } -String *Item_singlerow_subselect::val_str (String *str) +String *Item_singlerow_subselect::val_str (String *str) { if (!exec() && !value->null_value) { @@ -553,7 +553,7 @@ double Item_exists_subselect::val() return (double) value; } -longlong Item_exists_subselect::val_int() +longlong Item_exists_subselect::val_int() { DBUG_ASSERT(fixed == 1); if (exec()) @@ -590,7 +590,7 @@ double Item_in_subselect::val() return (double) value; } -longlong Item_in_subselect::val_int() +longlong Item_in_subselect::val_int() { DBUG_ASSERT(fixed == 1); if (exec()) @@ -842,7 +842,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, { // it is single select without tables => possible optimization item= func->create(left_expr, item); - // fix_field of item will be done in time of substituting + // fix_field of item will be done in time of substituting substitution= item; have_to_be_excluded= 1; if (thd->lex->describe) @@ -885,7 +885,7 @@ Item_in_subselect::row_value_transformer(JOIN *join) thd->where= "row IN/ALL/ANY subquery"; if (stmt) - thd->set_n_backup_item_arena(stmt, &backup); + thd->set_n_backup_item_arena(stmt, &backup); SELECT_LEX *select_lex= join->select_lex; @@ -926,7 +926,7 @@ Item_in_subselect::row_value_transformer(JOIN *join) List_iterator_fast li(select_lex->item_list); for (uint i= 0; i < n; i++) { - Item *func= new Item_ref_null_helper(this, + Item *func= new Item_ref_null_helper(this, select_lex->ref_pointer_array+i, (char *) "", (char *) ""); @@ -1108,7 +1108,7 @@ int subselect_single_select_engine::prepare() (ORDER*) select_lex->order_list.first, (ORDER*) select_lex->group_list.first, select_lex->having, - (ORDER*) 0, select_lex, + (ORDER*) 0, select_lex, select_lex->master_unit())) return 1; thd->lex->current_select= save_select; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 364781de362..6b8b8b0b3a7 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -47,7 +47,7 @@ protected: /* old engine if engine was changed */ subselect_engine *old_engine; /* cache of used external tables */ - table_map used_tables_cache; + table_map used_tables_cache; /* allowed number of columns (1 for single value subqueries) */ uint max_columns; /* work with 'substitution' */ @@ -69,17 +69,17 @@ public: virtual subs_type substype() { return UNKNOWN_SUBS; } - /* + /* We need this method, because some compilers do not allow 'this' pointer in constructor initialization list, but we need pass pointer to subselect Item class to select_subselect classes constructor. */ - virtual void init (st_select_lex *select_lex, + virtual void init (st_select_lex *select_lex, select_subselect *result); ~Item_subselect(); void cleanup(); - virtual void reset() + virtual void reset() { null_value= 1; } @@ -275,7 +275,7 @@ public: } virtual ~subselect_engine() {}; // to satisfy compiler virtual void cleanup()= 0; - + // set_thd should be called before prepare() void set_thd(THD *thd_arg) { thd= thd_arg; } THD * get_thd() { return thd; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 91df364e531..4305bee42a2 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1706,6 +1706,7 @@ static void reset_stmt_for_execute(Prepared_statement *stmt) unit->reinit_exec_mechanism(); } } + stmt->lex->current_select= &stmt->lex->select_lex; } From 74f3da33bf44c6dfd4d6e8f2fff876099bfc0777 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Mon, 12 Jul 2004 14:12:53 +0300 Subject: [PATCH 02/30] srv0start.c: innobase_start_or_create_for_mysql(): Rename innodb.status. to innodb_status. to avoid problems on VMS --- innobase/srv/srv0start.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 0fb8da9fe3a..3223854652f 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1026,7 +1026,7 @@ NetWare. */ srv_monitor_file_name = mem_alloc( strlen(fil_path_to_mysql_datadir) + 20 + sizeof "/innodb_status."); - sprintf(srv_monitor_file_name, "%s/innodb.status.%lu", + sprintf(srv_monitor_file_name, "%s/innodb_status.%lu", fil_path_to_mysql_datadir, os_proc_get_number()); srv_monitor_file = fopen(srv_monitor_file_name, "w+"); if (!srv_monitor_file) { From bea2f4305ee6b418b9ad4d8309cbdb8e913ed054 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Mon, 12 Jul 2004 15:13:18 +0300 Subject: [PATCH 03/30] InnoDB: Increment the lock wait watchdog timeout during CHECK TABLE (Bug #2694) --- innobase/include/srv0srv.h | 1 + innobase/include/sync0arr.h | 2 +- innobase/row/row0mysql.c | 12 +++++++++++- innobase/srv/srv0srv.c | 3 +++ innobase/sync/sync0arr.c | 12 +++++++----- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 40a96e79973..0be13528fd7 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -149,6 +149,7 @@ extern ulint srv_test_n_mutexes; extern ulint srv_test_array_size; extern ulint srv_activity_count; +extern ulint srv_fatal_semaphore_wait_threshold; extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs, query threads, and lock table: we allocate diff --git a/innobase/include/sync0arr.h b/innobase/include/sync0arr.h index 383d0c69fb2..4324f2d3f2c 100644 --- a/innobase/include/sync0arr.h +++ b/innobase/include/sync0arr.h @@ -95,7 +95,7 @@ void sync_arr_wake_threads_if_sema_free(void); /*====================================*/ /************************************************************************** -Prints warnings of long semaphore waits to stderr. Currently > 120 sec. */ +Prints warnings of long semaphore waits to stderr. */ void sync_array_print_long_waits(void); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index b7779e5b7a3..e559ef739cc 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2805,7 +2805,12 @@ row_check_table_for_mysql( REPEATABLE READ here */ prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ; - + + /* Enlarge the fatal lock wait timeout during CHECK TABLE. */ + mutex_enter(&kernel_mutex); + srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */ + mutex_exit(&kernel_mutex); + index = dict_table_get_first_index(table); while (index != NULL) { @@ -2853,6 +2858,11 @@ row_check_table_for_mysql( ret = DB_ERROR; } + /* Restore the fatal lock wait timeout after CHECK TABLE. */ + mutex_enter(&kernel_mutex); + srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */ + mutex_exit(&kernel_mutex); + prebuilt->trx->op_info = (char *) ""; return(ret); diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index a78bd0d864c..174214f9efe 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -55,6 +55,9 @@ ibool srv_lower_case_table_names = FALSE; in the server */ ulint srv_activity_count = 0; +/* The following is the maximum allowed duration of a lock wait. */ +ulint srv_fatal_semaphore_wait_threshold = 600; + ibool srv_lock_timeout_and_monitor_active = FALSE; ibool srv_error_monitor_active = FALSE; diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c index 944503aa0e2..176aedb6ae3 100644 --- a/innobase/sync/sync0arr.c +++ b/innobase/sync/sync0arr.c @@ -890,7 +890,7 @@ sync_arr_wake_threads_if_sema_free(void) } /************************************************************************** -Prints warnings of long semaphore waits to stderr. Currently > 120 sec. */ +Prints warnings of long semaphore waits to stderr. */ void sync_array_print_long_waits(void) @@ -900,6 +900,7 @@ sync_array_print_long_waits(void) ibool old_val; ibool noticed = FALSE; ulint i; + ulint fatal_timeout = srv_fatal_semaphore_wait_threshold; for (i = 0; i < sync_primary_wait_array->n_cells; i++) { @@ -914,12 +915,13 @@ sync_array_print_long_waits(void) } if (cell->wait_object != NULL - && difftime(time(NULL), cell->reservation_time) > 600) { + && difftime(time(NULL), cell->reservation_time) + > fatal_timeout) { - fputs( -"InnoDB: Error: semaphore wait has lasted > 600 seconds\n" + fprintf(stderr, +"InnoDB: Error: semaphore wait has lasted > %lu seconds\n" "InnoDB: We intentionally crash the server, because it appears to be hung.\n", - stderr); + fatal_timeout); ut_error; } From a323342728791af8c7e7a857564cd63f0036497e Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Mon, 12 Jul 2004 16:47:22 +0300 Subject: [PATCH 04/30] InnoDB: LOCK TABLE clean-up --- innobase/include/lock0lock.h | 5 +++-- innobase/include/row0mysql.h | 7 ++++--- innobase/include/trx0trx.h | 5 +++-- innobase/lock/lock0lock.c | 32 +++++++++++++++++--------------- innobase/row/row0mysql.c | 9 +++++---- innobase/trx/trx0trx.c | 4 ++-- sql/ha_innodb.cc | 4 ++-- 7 files changed, 36 insertions(+), 30 deletions(-) diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index 9c5f35c6674..9f525042dcc 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -418,7 +418,8 @@ lock_release_off_kernel( /*====================*/ trx_t* trx); /* in: transaction */ /************************************************************************* -Releases table locks, and releases possible other transactions waiting +Releases table locks explicitly requested with LOCK TABLES (indicated by +lock type LOCK_TABLE_EXP), and releases possible other transactions waiting because of these locks. */ void @@ -548,7 +549,7 @@ extern lock_sys_t* lock_sys; /* Lock types */ #define LOCK_TABLE 16 /* these type values should be so high that */ #define LOCK_REC 32 /* they can be ORed to the lock mode */ -#define LOCK_TABLE_EXP 80 /* explicit table lock */ +#define LOCK_TABLE_EXP 80 /* explicit table lock (80 = 16 + 64) */ #define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the type_mode field in a lock */ /* Waiting lock flag */ diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index e088071a1c4..0ab70db2dea 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -153,11 +153,12 @@ row_lock_table_autoinc_for_mysql( row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL table handle */ /************************************************************************* -Unlocks a table lock possibly reserved by trx. */ +Unlocks all table locks explicitly requested by trx (with LOCK TABLES, +lock type LOCK_TABLE_EXP). */ void -row_unlock_table_for_mysql( -/*=======================*/ +row_unlock_tables_for_mysql( +/*========================*/ trx_t* trx); /* in: transaction */ /************************************************************************* Sets a table lock on the table mentioned in prebuilt. */ diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 07d5e5a8215..3be16e8f46d 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -423,8 +423,9 @@ struct trx_struct{ lock_t* auto_inc_lock; /* possible auto-inc lock reserved by the transaction; note that it is also in the lock list trx_locks */ - ulint n_tables_locked;/* number of table locks reserved by - the transaction, stored in trx_locks */ + ulint n_lock_table_exp;/* number of explicit table locks + (LOCK TABLES) reserved by the + transaction, stored in trx_locks */ UT_LIST_NODE_T(trx_t) trx_list; /* list of transactions */ UT_LIST_NODE_T(trx_t) diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 11bd1f93808..1c82d892d5f 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -2023,9 +2023,8 @@ lock_grant( lock->trx->auto_inc_lock = lock; } else if (lock_get_type(lock) == LOCK_TABLE_EXP) { - ut_ad(lock_get_mode(lock) == LOCK_S + ut_a(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); - lock->trx->n_tables_locked++; } if (lock_print_waits) { @@ -3203,6 +3202,10 @@ lock_table_create( lock->type_mode = type_mode | LOCK_TABLE; lock->trx = trx; + if ((lock->type_mode & LOCK_TABLE_EXP) == LOCK_TABLE_EXP) { + lock->trx->n_lock_table_exp++; + } + lock->un_member.tab_lock.table = table; UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock); @@ -3386,7 +3389,7 @@ lock_table( return(DB_SUCCESS); } - ut_ad(flags == 0 || flags == LOCK_TABLE_EXP); + ut_a(flags == 0 || flags == LOCK_TABLE_EXP); trx = thr_get_trx(thr); @@ -3418,10 +3421,7 @@ lock_table( lock_table_create(table, mode | flags, trx); - if (flags) { - ut_ad(mode == LOCK_S || mode == LOCK_X); - trx->n_tables_locked++; - } + ut_a(!flags || mode == LOCK_S || mode == LOCK_X); lock_mutex_exit_kernel(); @@ -3502,7 +3502,7 @@ lock_table_dequeue( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - ut_ad(lock_get_type(in_lock) == LOCK_TABLE || + ut_a(lock_get_type(in_lock) == LOCK_TABLE || lock_get_type(in_lock) == LOCK_TABLE_EXP); lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, in_lock); @@ -3607,9 +3607,9 @@ lock_release_off_kernel( lock_table_dequeue(lock); if (lock_get_type(lock) == LOCK_TABLE_EXP) { - ut_ad(lock_get_mode(lock) == LOCK_S + ut_a(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); - trx->n_tables_locked--; + trx->n_lock_table_exp--; } } @@ -3630,11 +3630,12 @@ lock_release_off_kernel( mem_heap_empty(trx->lock_heap); ut_a(trx->auto_inc_lock == NULL); - ut_a(trx->n_tables_locked == 0); + ut_a(trx->n_lock_table_exp == 0); } /************************************************************************* -Releases table locks, and releases possible other transactions waiting +Releases table locks explicitly requested with LOCK TABLES (indicated by +lock type LOCK_TABLE_EXP), and releases possible other transactions waiting because of these locks. */ void @@ -3659,7 +3660,7 @@ lock_release_tables_off_kernel( count++; if (lock_get_type(lock) == LOCK_TABLE_EXP) { - ut_ad(lock_get_mode(lock) == LOCK_S + ut_a(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); if (trx->insert_undo || trx->update_undo) { @@ -3675,7 +3676,8 @@ lock_release_tables_off_kernel( } lock_table_dequeue(lock); - trx->n_tables_locked--; + trx->n_lock_table_exp--; + lock = UT_LIST_GET_LAST(trx->trx_locks); continue; } @@ -3696,7 +3698,7 @@ lock_release_tables_off_kernel( mem_heap_empty(trx->lock_heap); - ut_a(trx->n_tables_locked == 0); + ut_a(trx->n_lock_table_exp == 0); } /************************************************************************* diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index e559ef739cc..98ab1a1e754 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -723,14 +723,15 @@ run_again: } /************************************************************************* -Unlocks a table lock possibly reserved by trx. */ +Unlocks all table locks explicitly requested by trx (with LOCK TABLES, +lock type LOCK_TABLE_EXP). */ void -row_unlock_table_for_mysql( -/*=======================*/ +row_unlock_tables_for_mysql( +/*========================*/ trx_t* trx) /* in: transaction */ { - if (!trx->n_tables_locked) { + if (!trx->n_lock_table_exp) { return; } diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 335e1f69228..576827966ab 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -151,7 +151,7 @@ trx_create( trx->n_tickets_to_enter_innodb = 0; trx->auto_inc_lock = NULL; - trx->n_tables_locked = 0; + trx->n_lock_table_exp = 0; trx->read_view_heap = mem_heap_create(256); trx->read_view = NULL; @@ -279,7 +279,7 @@ trx_free( ut_a(!trx->has_search_latch); ut_a(!trx->auto_inc_lock); - ut_a(!trx->n_tables_locked); + ut_a(!trx->n_lock_table_exp); ut_a(trx->dict_operation_lock_mode == 0); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index df193bde947..21dd7f748c2 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4656,8 +4656,8 @@ ha_innobase::external_lock( trx->n_mysql_tables_in_use--; prebuilt->mysql_has_locked = FALSE; auto_inc_counter_for_this_stat = 0; - if (trx->n_tables_locked) { - row_unlock_table_for_mysql(trx); + if (trx->n_lock_table_exp) { + row_unlock_tables_for_mysql(trx); } /* If the MySQL lock count drops to zero we know that the current SQL From 88369368f51cb08b92807e536e8a57e387076125 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Mon, 12 Jul 2004 17:14:13 +0300 Subject: [PATCH 05/30] InnoDB: LOCK TABLES clean-up, part 2 --- innobase/lock/lock0lock.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 1c82d892d5f..bc03a27c874 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -3508,6 +3508,10 @@ lock_table_dequeue( lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, in_lock); lock_table_remove_low(in_lock); + + if (lock_get_type(in_lock) == LOCK_TABLE_EXP) { + in_lock->trx->n_lock_table_exp--; + } /* Check if waiting locks in the queue can now be granted: grant locks if there are no conflicting locks ahead. */ @@ -3609,7 +3613,6 @@ lock_release_off_kernel( if (lock_get_type(lock) == LOCK_TABLE_EXP) { ut_a(lock_get_mode(lock) == LOCK_S || lock_get_mode(lock) == LOCK_X); - trx->n_lock_table_exp--; } } @@ -3676,7 +3679,6 @@ lock_release_tables_off_kernel( } lock_table_dequeue(lock); - trx->n_lock_table_exp--; lock = UT_LIST_GET_LAST(trx->trx_locks); continue; From 8542743833c1f2d42faf95307752f968df97ffd0 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 13 Jul 2004 08:57:55 +0200 Subject: [PATCH 06/30] s/help all/help contents/ bug#4527 --- client/mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index 98bc7e750e1..c9ee6819a13 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1727,7 +1727,7 @@ com_help(String *buffer __attribute__((unused)), commands[i].cmd_char, commands[i].doc); } if (connected && mysql_get_server_version(&mysql) >= 40100) - put_info("\nFor server side help, type 'help all'\n", INFO_INFO); + put_info("\nFor server side help, type 'help contents'\n", INFO_INFO); return 0; } From 141d43ef95ba8c6e1113cdaf5145b31786d7457d Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 13 Jul 2004 09:37:16 +0200 Subject: [PATCH 07/30] forced X/Open mode on HPUX removed. The correct way (that affects not only C but also C++ and linking) would be CFLAGS="-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_HPUX_SOURCE" CXXFLAGS="-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_HPUX_SOURCE" LDFLAGS="-lxnet" but apparently MySQL works without too. --- include/my_global.h | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 3c35ade8383..f7e77abfd26 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -120,26 +120,6 @@ #define __STDC_EXT__ 1 /* To get large file support on hpux */ #endif -#ifdef HPUX11 -/* - Fix warnings on HPUX11 - There is something really strange with HPUX11 include files as you get - error about wrongly declared symbols or missing defines if you don't - do the following: - */ -#if !defined(_XOPEN_SOURCE_EXTENDED) && ! defined(__cplusplus) -#define _XOPEN_SOURCE_EXTENDED 1 -#endif - -/* Fix type of socklen as this is depending on the above define */ -#undef SOCKET_SIZE_TYPE -#ifdef _XOPEN_SOURCE_EXTENDED -#define SOCKET_SIZE_TYPE socklen_t -#else -#define SOCKET_SIZE_TYPE int -#endif /* _XOPEN_SOURCE_EXTENDED */ -#endif /* HPUX11 */ - #if defined(THREAD) && !defined(__WIN__) && !defined(OS2) #ifndef _POSIX_PTHREAD_SEMANTICS #define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */ From b92d70b231f7bfe37d1969b0e7834c5286813973 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Tue, 13 Jul 2004 12:30:34 +0300 Subject: [PATCH 08/30] lock0lock.c: Decrement n_lock_table_exp in lock_table_remove_low() instead of lock_table_dequeue(). Do not empty lock_heap in lock_release_tables_off_kernel(). --- innobase/lock/lock0lock.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index bc03a27c874..68dd2aa18c1 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -3202,7 +3202,7 @@ lock_table_create( lock->type_mode = type_mode | LOCK_TABLE; lock->trx = trx; - if ((lock->type_mode & LOCK_TABLE_EXP) == LOCK_TABLE_EXP) { + if (lock_get_type(lock) == LOCK_TABLE_EXP) { lock->trx->n_lock_table_exp++; } @@ -3241,7 +3241,11 @@ lock_table_remove_low( if (lock == trx->auto_inc_lock) { trx->auto_inc_lock = NULL; } - + + if (lock_get_type(lock) == LOCK_TABLE_EXP) { + lock->trx->n_lock_table_exp--; + } + UT_LIST_REMOVE(trx_locks, trx->trx_locks, lock); UT_LIST_REMOVE(un_member.tab_lock.locks, table->locks, lock); } @@ -3509,10 +3513,6 @@ lock_table_dequeue( lock_table_remove_low(in_lock); - if (lock_get_type(in_lock) == LOCK_TABLE_EXP) { - in_lock->trx->n_lock_table_exp--; - } - /* Check if waiting locks in the queue can now be granted: grant locks if there are no conflicting locks ahead. */ @@ -3698,8 +3698,6 @@ lock_release_tables_off_kernel( lock = UT_LIST_GET_PREV(trx_locks, lock); } - mem_heap_empty(trx->lock_heap); - ut_a(trx->n_lock_table_exp == 0); } From 0d5e1365b46b9937c0b39b243d80f064ea1a5d98 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 13 Jul 2004 13:54:20 +0300 Subject: [PATCH 09/30] A fix for a long standing bug in LOAD DATA .. LOCAL ..' --- sql/sql_load.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/sql_load.cc b/sql/sql_load.cc index a3ba14373b2..501852b5de8 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -291,6 +291,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { if (transactional_table) ha_autocommit_or_rollback(thd,error); + if (read_file_from_client) + while (!read_info.next_line()) + ; if (mysql_bin_log.is_open()) { /* From c2ca8e1a7a00e805aa0de774c22d3e62646f140d Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Tue, 13 Jul 2004 13:50:06 +0200 Subject: [PATCH 10/30] - fixed tabbing and added several missing symbols (required for linking with PHP5) (thanks to Georg Richter for the patch) --- libmysql/libmysql.def | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index bbd5af6558d..38ac9505e4b 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -129,6 +129,18 @@ EXPORTS mysql_stmt_prepare mysql_stmt_init mysql_stmt_insert_id - mysql_stmt_attr_get - mysql_stmt_attr_set + mysql_stmt_attr_get + mysql_stmt_attr_set mysql_stmt_field_count + client_errors + mysql_set_local_infile_default + mysql_set_local_infile_handler + mysql_disable_reads_from_master + mysql_disable_rpl_parse + mysql_enable_reads_from_master + mysql_enable_rpl_parse + mysql_master_query + mysql_rpl_parse_enabled + mysql_rpl_probe + mysql_rpl_query_type + mysql_slave_query From a009af5e84b8f4632f9a0804ed6f0971e16b7ca8 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Tue, 13 Jul 2004 16:51:10 +0200 Subject: [PATCH 11/30] WL#1900 "When CHECK TABLE or ANALYZE TABLE of a MyISAM table is killed by KILL or shutdown, do not mark the table as corrupted". It is indeed more logical to leave the corruption flag unchanged. This cannot be extended to REPAIR/OPTIMIZE as they make no backup copy of the MYI. This patch was tested with KILL and mysqladmin shutdown while a CHECK TABLE was running. Without the patch, the table becomes unusable (can't INSERT to it, error 145). With the patch, no. --- sql/ha_myisam.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 77615d68fe4..51c8521c376 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -336,7 +336,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) HA_STATUS_CONST); } } - else if (!mi_is_crashed(file)) + else if (!mi_is_crashed(file) && !thd->killed) { mi_mark_crashed(file); file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; @@ -378,7 +378,7 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) error=update_state_info(¶m,file,UPDATE_STAT); pthread_mutex_unlock(&share->intern_lock); } - else if (!mi_is_crashed(file)) + else if (!mi_is_crashed(file) && !thd->killed) mi_mark_crashed(file); return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; } From 894142b66e9a88300d18bae026f632bec8a16923 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Tue, 13 Jul 2004 21:03:30 +0200 Subject: [PATCH 12/30] - Move checking of the MD5 checksumming to the correct place - fix calling of my_md5sum --- Build-tools/Do-compile | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 40a5cf38121..1650e3d4a09 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -169,6 +169,17 @@ info("PATH is $ENV{PATH}"); log_timestamp(); +$md5_result= safe_system("perl $ENV{HOME}/my_md5sum -c ${opt_distribution}.md5"); + +if ($md5_result != 0) +{ + abort("MD5 check failed for $opt_distribution!"); +} +else +{ + info("SUCCESS: MD5 checks for $opt_distribution"); +} + if (-x "$host/bin/mysqladmin") { log_system("$host/bin/mysqladmin $mysqladmin_args -S $mysql_unix_port -s shutdown"); @@ -202,17 +213,6 @@ if ($opt_stage == 0) safe_cd($host); if ($opt_stage == 0 && ! $opt_use_old_distribution) { - $md5_result= safe_system("./my_md5sum -c ${opt_distribution}.md5"); - - if ($md5_result != 0) - { - abort("MD5 failed for $opt_distribution!"); - } - else - { - info("SUCCESS: MD5 checks for $opt_distribution"); - } - safe_system("gunzip < $opt_distribution | $tar xf -"); # Fix file times; This is needed because the time for files may be @@ -332,7 +332,9 @@ $tar_file=<$pwd/$host/mysql*.t*gz>; abort ("Could not find tarball!") unless ($tar_file); # Generate the MD5 for the binary distribution -safe_system("./my_md5sum $tar_file > ${tar_file}.md5}"); +$tar_file=~ /(mysql[^\/]*)\.(tar\.gz|tgz)/; +$tar_file_lite= "$1.$2"; +system("cd $pwd/$host; perl $ENV{HOME}/my_md5sum $tar_file_lite > ${tar_file_lite}.md5"); # # Unpack the binary distribution From 80b363bca0b24098f45586759f18a424b477ed9d Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Tue, 13 Jul 2004 22:11:33 +0200 Subject: [PATCH 13/30] - Fixed a previous modification to the MySQL Startup Item for Mac OS X: the name of the startup script itself must match the name of the subdirectory it's located in. Changed MySQL->MySQLCOM in the Do-pkg script and renamed the file in BK. (Thanks to Bryan McCormack for reporting this) --- Build-tools/Do-pkg | 2 +- support-files/MacOSX/{MySQL => MySQLCOM} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename support-files/MacOSX/{MySQL => MySQLCOM} (96%) diff --git a/Build-tools/Do-pkg b/Build-tools/Do-pkg index 286e33f6dd4..b9df444a4ba 100755 --- a/Build-tools/Do-pkg +++ b/Build-tools/Do-pkg @@ -96,7 +96,7 @@ $SI_PARAMS= <$SUPFILEDIR/StartupParameters.plist>; $SI_POST= <$SUPFILEDIR/StartupItem.postinstall>; $SI_NAME= "MySQLStartupItem"; $SI_DIR_NAME= "MySQLCOM"; -$SI_SCRIPT= <$SUPFILEDIR/MySQL>; +$SI_SCRIPT= <$SUPFILEDIR/MySQLCOM>; @RESOURCES= qw/ ReadMe.txt postinstall preinstall /; @LICENSES= ("$SRCBASEDIR/COPYING","$SRCBASEDIR/MySQLEULA.txt"); diff --git a/support-files/MacOSX/MySQL b/support-files/MacOSX/MySQLCOM similarity index 96% rename from support-files/MacOSX/MySQL rename to support-files/MacOSX/MySQLCOM index f6579700384..9be5edb56f7 100755 --- a/support-files/MacOSX/MySQL +++ b/support-files/MacOSX/MySQLCOM @@ -1,6 +1,6 @@ #!/bin/sh # -# /Library/StartupItems/MySQL/MySQL +# /Library/StartupItems/MySQLCOM/MySQLCOM # # A script to automatically start up MySQL on system bootup # for Mac OS X. This is actually just a wrapper script around From d764fb4240680334adb800a379ab980c5c107512 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 14 Jul 2004 09:10:49 +0200 Subject: [PATCH 14/30] - fixed file name of the MySQL startup item script to MySQLCOM, so it's included in the source distribution --- support-files/MacOSX/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/MacOSX/Makefile.am b/support-files/MacOSX/Makefile.am index ff16fa3235a..6babcf97b7a 100644 --- a/support-files/MacOSX/Makefile.am +++ b/support-files/MacOSX/Makefile.am @@ -23,7 +23,7 @@ EXTRA_DIST = Info.plist.sh \ postinstall.sh \ preinstall.sh \ ReadMe.txt \ - MySQL \ + MySQLCOM \ StartupItem.Description.plist \ StartupItem.Info.plist \ StartupItem.postinstall From 791bdf2c480188119a0666423bef1ea3a3adadaf Mon Sep 17 00:00:00 2001 From: "paul@kite-hub.kitebird.com" <> Date: Wed, 14 Jul 2004 11:33:00 -0500 Subject: [PATCH 15/30] mysql_fix_privilege_tables.sh: Language fixups. --- scripts/mysql_fix_privilege_tables.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index 79b4bc627b7..c9e8e0c4dfd 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -159,11 +159,11 @@ s_echo() fi } -s_echo "This scripts updates all the mysql privilege tables to be usable by" +s_echo "This script updates all the mysql privilege tables to be usable by" s_echo "MySQL 4.0 and above." s_echo "" s_echo "This is needed if you want to use the new GRANT functions," -s_echo "CREATE AGGREGATE FUNCTION or want to use the more secure passwords in 4.1" +s_echo "CREATE AGGREGATE FUNCTION, or the more secure passwords in 4.1" s_echo "" if test $verbose = 1 From 3609ab683e42a0c48226032508b68e5a8043f0b1 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 14 Jul 2004 23:57:14 +0300 Subject: [PATCH 16/30] stack overflow check added for subqueries processing (BUG#4554) --- sql/item_subselect.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 4c1ffeecc97..3d5a11a26bc 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -128,7 +128,12 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) stmt= thd->current_statement; char const *save_where= thd->where; - int res= engine->prepare(); + int res; + + if (check_stack_overrun(thd, (gptr)&res)) + return 1; + + res= engine->prepare(); // all transformetion is done (used by prepared statements) changed= 1; From 0614f8c718a23da7d24a6745d9f2cdc611999e81 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 15 Jul 2004 09:08:51 +0300 Subject: [PATCH 17/30] btr0cur.c: Do not add + 1 to the InnoDB index cardinality estimate if the B-tree just contains one page; the fix made in March 2004 caused InnoDB systematically to overestimate the cardinality of empty or small tables by 1 --- innobase/btr/btr0cur.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index 8974200efe8..b07b06765e6 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -2707,8 +2707,11 @@ btr_estimate_number_of_different_key_vals( rec = page_rec_get_next(rec); } + if (n_cols == dict_index_get_n_unique_in_tree(index)) { - /* We add one because we know that the first record + + /* If there is more than one leaf page in the tree, + we add one because we know that the first record on the page certainly had a different prefix than the last record on the previous index page in the alphabetical order. Before this fix, if there was @@ -2716,7 +2719,11 @@ btr_estimate_number_of_different_key_vals( algorithm grossly underestimated the number of rows in the table. */ - n_diff[n_cols]++; + if (btr_page_get_prev(page, &mtr) != FIL_NULL + || btr_page_get_next(page, &mtr) != FIL_NULL) { + + n_diff[n_cols]++; + } } total_external_size += From 8ab5398bf770c443d0f5869956ed897fea0dbf12 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Thu, 15 Jul 2004 14:17:30 +0300 Subject: [PATCH 18/30] check that all system tables deleted added --- mysql-test/r/system_mysql_db.result | 2 ++ mysql-test/t/system_mysql_db.test | 5 +++++ mysql-test/t/system_mysql_db_fix.test | 14 ++++---------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result index 1f09a20abc5..3fbe842ce49 100644 --- a/mysql-test/r/system_mysql_db.result +++ b/mysql-test/r/system_mysql_db.result @@ -126,3 +126,5 @@ columns_priv CREATE TABLE `columns_priv` ( `Column_priv` set('Select','Insert','Update','References') NOT NULL default '', PRIMARY KEY (`Host`,`Db`,`User`,`Table_name`,`Column_name`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='Column privileges' +show tables; +Tables_in_test diff --git a/mysql-test/t/system_mysql_db.test b/mysql-test/t/system_mysql_db.test index 85a2f7f9bae..a6d683489c3 100644 --- a/mysql-test/t/system_mysql_db.test +++ b/mysql-test/t/system_mysql_db.test @@ -6,3 +6,8 @@ use mysql; -- enable_query_log -- source include/system_db_struct.inc +-- disable_query_log +use test; +-- enable_query_log +# keep results same with system_mysql_db_fix +show tables; diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix.test index 13c83fc9012..6c44535e3b7 100644 --- a/mysql-test/t/system_mysql_db_fix.test +++ b/mysql-test/t/system_mysql_db_fix.test @@ -68,15 +68,9 @@ INSERT INTO user VALUES ('localhost','', '','N','N','N','N','N','N','N','N',' -- disable_query_log -DROP TABLE db; -DROP TABLE host; -DROP TABLE user; -DROP TABLE func; -DROP TABLE tables_priv; -DROP TABLE columns_priv; -DROP TABLE help_category; -DROP TABLE help_keyword; -DROP TABLE help_relation; -DROP TABLE help_topic; +DROP TABLE db, host, user, func, tables_priv, columns_priv, help_category, help_keyword, help_relation, help_topic, time_zone, time_zone_leap_second, time_zone_name, time_zone_transition, time_zone_transition_type; -- enable_query_log + +# check that we droped all system tables +show tables; From 20b60510e9f5c33eaf19409973b2d06d7580f0f2 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Thu, 15 Jul 2004 15:46:22 +0300 Subject: [PATCH 19/30] InnoDB: limit the recursion depth for ON (UPDATE|DELETE) CASCADE (Bug #4446) --- innobase/row/row0ins.c | 78 +++++++++++++++++++++++++++++++------- mysql-test/r/innodb.result | 12 ++++++ mysql-test/t/innodb.test | 14 +++++++ 3 files changed, 91 insertions(+), 13 deletions(-) diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 93d360eaaeb..458970da4e2 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -370,6 +370,32 @@ row_ins_cascade_ancestor_updates_table( return(FALSE); } +/************************************************************************* +Returns the number of ancestor UPDATE or DELETE nodes of a +cascaded update/delete node. */ +static +ulint +row_ins_cascade_n_ancestors( +/*========================*/ + /* out: number of ancestors */ + que_node_t* node) /* in: node in a query graph */ +{ + que_node_t* parent; + ulint n_ancestors = 0; + + parent = que_node_get_parent(node); + + while (que_node_get_type(parent) == QUE_NODE_UPDATE) { + n_ancestors++; + + parent = que_node_get_parent(parent); + + ut_a(parent); + } + + return(n_ancestors); +} + /********************************************************************** Calculates the update vector node->cascade->update for a child table in a cascaded update. */ @@ -615,6 +641,34 @@ row_ins_foreign_report_add_err( mutex_exit(&dict_foreign_err_mutex); } +/************************************************************************* +Invalidate the query cache for the given table. */ +static +void +row_ins_invalidate_query_cache( +/*===========================*/ + que_thr_t* thr, /* in: query thread whose run_node + is an update node */ + const char* name) /* in: table name prefixed with + database name and a '/' character */ +{ + char* buf; + char* ptr; + ulint len = strlen(name) + 1; + + buf = mem_strdupl(name, len); + + ptr = strchr(buf, '/'); + ut_a(ptr); + *ptr = '\0'; + + /* We call a function in ha_innodb.cc */ +#ifndef UNIV_HOTBACKUP + innobase_invalidate_query_cache(thr_get_trx(thr), buf, len); +#endif + mem_free(buf); +} + /************************************************************************* Perform referential actions or checks when a parent row is deleted or updated and the constraint had an ON DELETE or ON UPDATE condition which was not @@ -650,26 +704,14 @@ row_ins_foreign_check_on_constraint( ulint n_to_update; ulint err; ulint i; - char* ptr; - char table_name_buf[1000]; ut_a(thr && foreign && pcur && mtr); /* Since we are going to delete or update a row, we have to invalidate the MySQL query cache for table */ - ut_a(ut_strlen(table->name) < 998); - strcpy(table_name_buf, table->name); + row_ins_invalidate_query_cache(thr, table->name); - ptr = strchr(table_name_buf, '/'); - ut_a(ptr); - *ptr = '\0'; - - /* We call a function in ha_innodb.cc */ -#ifndef UNIV_HOTBACKUP - innobase_invalidate_query_cache(thr_get_trx(thr), table_name_buf, - ut_strlen(table->name) + 1); -#endif node = thr->run_node; if (node->is_delete && 0 == (foreign->type & @@ -756,6 +798,16 @@ row_ins_foreign_check_on_constraint( goto nonstandard_exit_func; } + if (row_ins_cascade_n_ancestors(cascade) >= 15) { + err = DB_ROW_IS_REFERENCED; + + row_ins_foreign_report_err( +(char*)"Trying a too deep cascaded delete or update\n", + thr, foreign, btr_pcur_get_rec(pcur), entry); + + goto nonstandard_exit_func; + } + index = btr_pcur_get_btr_cur(pcur)->index; ut_a(index == foreign->foreign_index); diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 6a67bbc6f8b..c282ec68c78 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1259,3 +1259,15 @@ Cannot delete or update a parent row: a foreign key constraint fails update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; Unknown table 't1' in where clause drop table t3,t2,t1; +create table t1( +id int primary key, +pid int, +index(pid), +foreign key(pid) references t1(id) on delete cascade) type=innodb; +insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6), +(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14); +delete from t1 where id=0; +Cannot delete or update a parent row: a foreign key constraint fails +delete from t1 where id=15; +delete from t1 where id=0; +drop table t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 04642ddd619..34eabcc22df 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -896,3 +896,17 @@ update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id --error 1109 update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; drop table t3,t2,t1; + +create table t1( + id int primary key, + pid int, + index(pid), + foreign key(pid) references t1(id) on delete cascade) type=innodb; +insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6), + (8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14); +-- error 1217 +delete from t1 where id=0; +delete from t1 where id=15; +delete from t1 where id=0; + +drop table t1; From fe2425b7254bd403f607ad53990213e9948b6e16 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Thu, 15 Jul 2004 21:18:31 +0200 Subject: [PATCH 20/30] - Avoid the error message "Can't read index header from..." when copying a small index file because the value returned for $length is < 1024. This can happen if the filehandle was open()ed as an UTF-8 encoded file with Unicode characters (In this case read() returns characters not bytes) (Thanks to Mike Bethune) for this hint) --- scripts/mysqlhotcopy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index af4e6084c59..fe93aa5a1bc 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -635,6 +635,7 @@ sub copy_index my $to="$target/$file"; my $buff; open(INPUT, "<$from") || die "Can't open file $from: $!\n"; + binmode(INPUT, ":raw"); my $length=read INPUT, $buff, 2048; die "Can't read index header from $from\n" if ($length < 1024); close INPUT; From 0452d59d222c71dc01b2453ed4ec6a512d01197e Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Fri, 16 Jul 2004 13:21:58 +0200 Subject: [PATCH 21/30] in 4.1 DATABASE() may be NULL --- sql/item_strfunc.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 22134733393..08123370bc6 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -359,9 +359,10 @@ class Item_func_database :public Item_str_func public: Item_func_database() { collation.set(system_charset_info,DERIVATION_IMPLICIT); } String *val_str(String *); - void fix_length_and_dec() - { + void fix_length_and_dec() + { max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen; + maybe_null=1; } const char *func_name() const { return "database"; } }; From f973ac9942265954a9dca65bf10d8f4ae7c4d1c4 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sat, 17 Jul 2004 02:09:25 +0300 Subject: [PATCH 22/30] test fix --- mysql-test/r/func_system.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/func_system.result b/mysql-test/r/func_system.result index 671132428c5..d3db2cc5151 100644 --- a/mysql-test/r/func_system.result +++ b/mysql-test/r/func_system.result @@ -46,7 +46,7 @@ create table t1 (version char(40)) select database(), user(), version() as 'vers show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `database()` char(34) character set utf8 NOT NULL default '', + `database()` char(34) character set utf8 default NULL, `user()` char(77) character set utf8 NOT NULL default '', `version` char(40) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 From 88e00cd919cf36cc867a48aaadf8b71311c6498e Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 17 Jul 2004 16:58:16 +0200 Subject: [PATCH 23/30] Fixes for BUG#4506 "mysqlbinlog --position --read-from-remote-server has wrong "# at" lines", BUG#4553 "Multi-table DROP TABLE replicates improperly for nonexistent table" with a test file. It was not possible to add a test for BUG#4506 as in the test suite we must use --short-form which does not display the "# at" lines. --- client/mysqlbinlog.cc | 4 ++-- mysql-test/r/rpl_drop.result | 10 ++++++++++ mysql-test/t/rpl_drop.test | 10 ++++++++++ sql/sql_table.cc | 35 +++++++++++++++++++---------------- 4 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 mysql-test/r/rpl_drop.result create mode 100644 mysql-test/t/rpl_drop.test diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 7bceedea4fe..7c3d22c4900 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -723,8 +723,8 @@ static int dump_remote_log_entries(const char* logname) */ if (old_off) old_off+= len-1; - else - old_off= BIN_LOG_HEADER_SIZE; + else // first event, so it's a fake Rotate event + old_off= position; } return 0; } diff --git a/mysql-test/r/rpl_drop.result b/mysql-test/r/rpl_drop.result new file mode 100644 index 00000000000..ce1f5b6ee81 --- /dev/null +++ b/mysql-test/r/rpl_drop.result @@ -0,0 +1,10 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +drop table if exists t1, t2; +create table t1 (a int); +drop table t1, t2; +Unknown table 't2' diff --git a/mysql-test/t/rpl_drop.test b/mysql-test/t/rpl_drop.test new file mode 100644 index 00000000000..6fc2500fc97 --- /dev/null +++ b/mysql-test/t/rpl_drop.test @@ -0,0 +1,10 @@ +# Testcase for BUG#4552 (DROP on two tables, one of which does not +# exist, must be binlogged with a non-zero error code) +source include/master-slave.inc; +drop table if exists t1, t2; +create table t1 (a int); +--error 1051; +drop table t1, t2; +save_master_pos; +connection slave; +sync_with_master; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1b956779832..9ab4859bc13 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -230,23 +230,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, wrong_tables.append(String(table->real_name)); } } - if (some_tables_deleted || tmp_table_deleted) - { - query_cache_invalidate3(thd, tables, 0); - if (!dont_log_query) - { - mysql_update_log.write(thd, thd->query,thd->query_length); - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, - tmp_table_deleted && !some_tables_deleted); - mysql_bin_log.write(&qinfo); - } - } - } - unlock_table_names(thd, tables); error= 0; if (wrong_tables.length()) { @@ -256,6 +240,25 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, my_error(ER_ROW_IS_REFERENCED,MYF(0)); error= 1; } + + if (some_tables_deleted || tmp_table_deleted) + { + query_cache_invalidate3(thd, tables, 0); + if (!dont_log_query) + { + mysql_update_log.write(thd, thd->query,thd->query_length); + if (mysql_bin_log.is_open()) + { + if (!error) + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, + tmp_table_deleted && !some_tables_deleted); + mysql_bin_log.write(&qinfo); + } + } + } + + unlock_table_names(thd, tables); DBUG_RETURN(error); } From e5c2285782028f99e28b2e213cc2415520245bdd Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sun, 18 Jul 2004 14:34:35 +0200 Subject: [PATCH 24/30] Fix for BUG#4551 "Temporary InnoDB tables not replicated properly with CREATE TABLE .. SELECT" The problem was that (for any storage engine), the created temporary table was not removed if CREATE SELECT failed (because of a constraint violation for example). This was not consistent with the manual and with CREATE SELECT (no TEMPORARY). --- mysql-test/r/create_select_tmp.result | 19 +++++++++++++++++++ mysql-test/t/create_select_tmp.test | 27 +++++++++++++++++++++++++++ sql/sql_insert.cc | 8 ++++++-- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/create_select_tmp.result create mode 100644 mysql-test/t/create_select_tmp.test diff --git a/mysql-test/r/create_select_tmp.result b/mysql-test/r/create_select_tmp.result new file mode 100644 index 00000000000..610ee70b3e3 --- /dev/null +++ b/mysql-test/r/create_select_tmp.result @@ -0,0 +1,19 @@ +drop table if exists t1, t2; +CREATE TABLE t1 ( a int ); +INSERT INTO t1 VALUES (1),(2),(1); +CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; +Duplicate entry '1' for key 1 +select * from t2; +Table 'test.t2' doesn't exist +CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; +Duplicate entry '1' for key 1 +select * from t2; +Table 'test.t2' doesn't exist +CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; +Duplicate entry '1' for key 1 +select * from t2; +Table 'test.t2' doesn't exist +CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; +Duplicate entry '1' for key 1 +select * from t2; +Table 'test.t2' doesn't exist diff --git a/mysql-test/t/create_select_tmp.test b/mysql-test/t/create_select_tmp.test new file mode 100644 index 00000000000..36292abd899 --- /dev/null +++ b/mysql-test/t/create_select_tmp.test @@ -0,0 +1,27 @@ +# Testcase for BUG#4551 +# The bug was that when the table was TEMPORARY, it was not deleted if +# the CREATE SELECT failed (the code intended too, but it actually +# didn't). And as the CREATE TEMPORARY TABLE was not written to the +# binlog if it was a transactional table, it resulted in an +# inconsistency between binlog and the internal list of temp tables. + +-- source include/have_innodb.inc +drop table if exists t1, t2; +CREATE TABLE t1 ( a int ); +INSERT INTO t1 VALUES (1),(2),(1); +--error 1062; +CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; +--error 1146; +select * from t2; +--error 1062; +CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; +--error 1146; +select * from t2; +--error 1062; +CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; +--error 1146; +select * from t2; +--error 1062; +CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; +--error 1146; +select * from t2; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 94e2f8f8850..8912c1faf2a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1545,9 +1545,13 @@ void select_create::abort() table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); enum db_type table_type=table->db_type; if (!table->tmp_table) + { hash_delete(&open_cache,(byte*) table); - if (!create_info->table_existed) - quick_rm_table(table_type,db,name); + if (!create_info->table_existed) + quick_rm_table(table_type, db, name); + } + else if (!create_info->table_existed) + close_temporary_table(thd, db, name); table=0; } VOID(pthread_mutex_unlock(&LOCK_open)); From 1ed37f97a3bc1b3b3a08f39489ebf3f5ad1d703e Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Mon, 19 Jul 2004 12:32:36 +0200 Subject: [PATCH 25/30] - only include the GPL license in the LICENSE text, not the FOSS exception (it only applies to 4.0 and above) --- Docs/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/Makefile.am b/Docs/Makefile.am index eea93380b35..5d66d236df1 100644 --- a/Docs/Makefile.am +++ b/Docs/Makefile.am @@ -139,7 +139,7 @@ INSTALL-BINARY: mysql.info $(GT) perl -w $(GT) mysql.info "Installing binary" "Installing source" > $@ ../COPYING: mysql.info $(GT) - perl -w $(GT) mysql.info "GPL license" "LGPL license" > $@ + perl -w $(GT) mysql.info "GPL license" "MySQL FOSS License Exception" > $@ # Don't update the files from bitkeeper %::SCCS/s.% From acfcf762281260f1000c0feb959690c8828edb73 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 19 Jul 2004 16:01:53 +0200 Subject: [PATCH 26/30] make acl_init() more robust - don't be confused if new privilege - ENUM ('N','Y') - columns are added (mostly because of downgrade) don't expect NOT NULL fields to never contain a NULL :) - somebody may've changed table definition, or we may be reading the wrong column --- sql/sql_acl.cc | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fa8065a5fc3..fddd5b70a2f 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -64,7 +64,7 @@ static DYNAMIC_ARRAY acl_wild_hosts; static hash_filo *acl_cache; static uint grant_version=0; static uint priv_version=0; /* Version of priv tables. incremented by acl_init */ -static ulong get_access(TABLE *form,uint fieldnr); +static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0); static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b); static ulong get_sort(uint count,...); static void init_check_host(void); @@ -299,13 +299,14 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) } else // password is correct { - user.access= get_access(table,3) & GLOBAL_ACLS; + uint next_field; + user.access= get_access(table,3,&next_field) & GLOBAL_ACLS; user.sort= get_sort(2,user.host.hostname,user.user); user.hostname_length= (user.host.hostname ? (uint) strlen(user.host.hostname) : 0); if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */ { - char *ssl_type=get_field(&mem, table->field[24]); + char *ssl_type=get_field(&mem, table->field[next_field++]); if (!ssl_type) user.ssl_type=SSL_TYPE_NONE; else if (!strcmp(ssl_type, "ANY")) @@ -315,16 +316,16 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) else /* !strcmp(ssl_type, "SPECIFIED") */ user.ssl_type=SSL_TYPE_SPECIFIED; - user.ssl_cipher= get_field(&mem, table->field[25]); - user.x509_issuer= get_field(&mem, table->field[26]); - user.x509_subject= get_field(&mem, table->field[27]); + user.ssl_cipher= get_field(&mem, table->field[next_field++]); + user.x509_issuer= get_field(&mem, table->field[next_field++]); + user.x509_subject= get_field(&mem, table->field[next_field++]); - char *ptr = get_field(&mem, table->field[28]); - user.user_resource.questions=atoi(ptr); - ptr = get_field(&mem, table->field[29]); - user.user_resource.updates=atoi(ptr); - ptr = get_field(&mem, table->field[30]); - user.user_resource.connections=atoi(ptr); + char *ptr = get_field(&mem, table->field[next_field++]); + user.user_resource.questions=ptr ? atoi(ptr) : 0; + ptr = get_field(&mem, table->field[next_field++]); + user.user_resource.updates=ptr ? atoi(ptr) : 0; + ptr = get_field(&mem, table->field[next_field++]); + user.user_resource.connections=ptr ? atoi(ptr) : 0; if (user.user_resource.questions || user.user_resource.updates || user.user_resource.connections) mqh_used=1; @@ -489,11 +490,24 @@ void acl_reload(THD *thd) /* Get all access bits from table after fieldnr - We know that the access privileges ends when there is no more fields - or the field is not an enum with two elements. + + IMPLEMENTATION + We know that the access privileges ends when there is no more fields + or the field is not an enum with two elements. + + SYNOPSIS + get_access() + form an open table to read privileges from. + The record should be already read in table->record[0] + fieldnr number of the first privilege (that is ENUM('N','Y') field + next_field on return - number of the field next to the last ENUM + (unless next_field == 0) + + RETURN VALUE + privilege mask */ -static ulong get_access(TABLE *form, uint fieldnr) +static ulong get_access(TABLE *form, uint fieldnr, uint *next_field) { ulong access_bits=0,bit; char buff[2]; @@ -503,12 +517,14 @@ static ulong get_access(TABLE *form, uint fieldnr) for (pos=form->field+fieldnr, bit=1; *pos && (*pos)->real_type() == FIELD_TYPE_ENUM && ((Field_enum*) (*pos))->typelib->count == 2 ; - pos++ , bit<<=1) + pos++, fieldnr++, bit<<=1) { (*pos)->val_str(&res); if (my_toupper(&my_charset_latin1, res[0]) == 'Y') access_bits|= bit; } + if (next_field) + *next_field=fieldnr; return access_bits; } From e2d6d838e1fa233aef9817b2ab53050b9aacf1cc Mon Sep 17 00:00:00 2001 From: "paul@ice.snake.net" <> Date: Mon, 19 Jul 2004 15:09:21 -0500 Subject: [PATCH 27/30] handler.cc: Revise output of SHOW ENGINES. --- sql/handler.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 017b9d9d4c8..41a252e3088 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -62,21 +62,21 @@ static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES; struct show_table_type_st sys_table_types[]= { {"MyISAM", &have_yes, - "Default type from 3.23 with great performance", DB_TYPE_MYISAM}, + "Default engine as of MySQL 3.23 with great performance", DB_TYPE_MYISAM}, {"HEAP", &have_yes, - "Hash based, stored in memory, useful for temporary tables", DB_TYPE_HEAP}, + "Alias for MEMORY", DB_TYPE_HEAP}, {"MEMORY", &have_yes, - "Alias for HEAP", DB_TYPE_HEAP}, + "Hash based, stored in memory, useful for temporary tables", DB_TYPE_HEAP}, {"MERGE", &have_yes, "Collection of identical MyISAM tables", DB_TYPE_MRG_MYISAM}, {"MRG_MYISAM",&have_yes, "Alias for MERGE", DB_TYPE_MRG_MYISAM}, {"ISAM", &have_isam, - "Obsolete table type; Is replaced by MyISAM", DB_TYPE_ISAM}, + "Obsolete storage engine, now replaced by MyISAM", DB_TYPE_ISAM}, {"MRG_ISAM", &have_isam, - "Obsolete table type; Is replaced by MRG_MYISAM", DB_TYPE_MRG_ISAM}, + "Obsolete storage engine, now replaced by MERGE", DB_TYPE_MRG_ISAM}, {"InnoDB", &have_innodb, - "Supports transactions, row-level locking and foreign keys", DB_TYPE_INNODB}, + "Supports transactions, row-level locking, and foreign keys", DB_TYPE_INNODB}, {"INNOBASE", &have_innodb, "Alias for INNODB", DB_TYPE_INNODB}, {"BDB", &have_berkeley_db, @@ -84,7 +84,7 @@ struct show_table_type_st sys_table_types[]= {"BERKELEYDB",&have_berkeley_db, "Alias for BDB", DB_TYPE_BERKELEY_DB}, {"NDBCLUSTER", &have_ndbcluster, - "Clustered, fault tolerant memory based tables", DB_TYPE_NDBCLUSTER}, + "Clustered, fault-tolerant, memory-based tables", DB_TYPE_NDBCLUSTER}, {"NDB", &have_ndbcluster, "Alias for NDBCLUSTER", DB_TYPE_NDBCLUSTER}, {"EXAMPLE",&have_example_db, From c9656ba5515848b441dfd8fbbc760aa78e941544 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Mon, 19 Jul 2004 15:12:23 -0700 Subject: [PATCH 28/30] Compilation failure on Windows fixed. --- sql/sql_db.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index d3804b972c8..43a683db9de 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -224,7 +224,8 @@ void del_dbopt(const char *path) { my_dbopt_t *opt; rw_wrlock(&LOCK_dboptions); - if ((opt= (my_dbopt_t *)hash_search(&dboptions, path, strlen(path)))) + if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const byte*) path, + strlen(path)))) hash_delete(&dboptions, (byte*) opt); rw_unlock(&LOCK_dboptions); } From 9de748d1d3569266f8e084116ea29ed6daf5665d Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 20 Jul 2004 11:00:10 +0200 Subject: [PATCH 29/30] results fixed after merge --- mysql-test/r/create_select_tmp.result | 16 ++++++++-------- mysql-test/r/endspace.result | 2 +- mysql-test/r/innodb.result | 12 ++++++++++++ mysql-test/r/ps_1general.result | 14 +++++++------- mysql-test/r/rpl_drop.result | 6 +++--- mysql-test/r/subselect2.result | 4 ++-- mysql-test/t/create_select_tmp.test | 2 ++ mysql-test/t/rpl_drop.test | 2 ++ 8 files changed, 37 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/create_select_tmp.result b/mysql-test/r/create_select_tmp.result index 610ee70b3e3..09ffc9013c7 100644 --- a/mysql-test/r/create_select_tmp.result +++ b/mysql-test/r/create_select_tmp.result @@ -2,18 +2,18 @@ drop table if exists t1, t2; CREATE TABLE t1 ( a int ); INSERT INTO t1 VALUES (1),(2),(1); CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; -Duplicate entry '1' for key 1 +ERROR 23000: Duplicate entry '1' for key 1 select * from t2; -Table 'test.t2' doesn't exist +ERROR 42S02: Table 'test.t2' doesn't exist CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1; -Duplicate entry '1' for key 1 +ERROR 23000: Duplicate entry '1' for key 1 select * from t2; -Table 'test.t2' doesn't exist +ERROR 42S02: Table 'test.t2' doesn't exist CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; -Duplicate entry '1' for key 1 +ERROR 23000: Duplicate entry '1' for key 1 select * from t2; -Table 'test.t2' doesn't exist +ERROR 42S02: Table 'test.t2' doesn't exist CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1; -Duplicate entry '1' for key 1 +ERROR 23000: Duplicate entry '1' for key 1 select * from t2; -Table 'test.t2' doesn't exist +ERROR 42S02: Table 'test.t2' doesn't exist diff --git a/mysql-test/r/endspace.result b/mysql-test/r/endspace.result index d2519523f36..4800bbf4ecb 100644 --- a/mysql-test/r/endspace.result +++ b/mysql-test/r/endspace.result @@ -157,7 +157,7 @@ teststring teststring explain select * from t1 order by text1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL key1 32 NULL 4 Using index +1 SIMPLE t1 index NULL key1 32 NULL 3 Using index alter table t1 modify text1 char(32) binary not null; select * from t1 order by text1; text1 diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 83d042cd279..9d830367745 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1345,6 +1345,18 @@ ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fail update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id; ERROR 42S02: Unknown table 't1' in where clause drop table t3,t2,t1; +create table t1( +id int primary key, +pid int, +index(pid), +foreign key(pid) references t1(id) on delete cascade) engine=innodb; +insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6), +(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14); +delete from t1 where id=0; +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails +delete from t1 where id=15; +delete from t1 where id=0; +drop table t1; CREATE TABLE t1 (col1 int(1))ENGINE=InnoDB; CREATE TABLE t2 (col1 int(1),stamp TIMESTAMP,INDEX stamp_idx (stamp))ENGINE=InnoDB; diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index b9df6187a09..e0a2a364e45 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -302,18 +302,18 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye prepare stmt4 from ' show storage engines '; execute stmt4; Engine Support Comment -MyISAM YES/NO Default type from 3.23 with great performance -HEAP YES/NO Hash based, stored in memory, useful for temporary tables -MEMORY YES/NO Alias for HEAP +MyISAM YES/NO Default engine as of MySQL 3.23 with great performance +HEAP YES/NO Alias for MEMORY +MEMORY YES/NO Hash based, stored in memory, useful for temporary tables MERGE YES/NO Collection of identical MyISAM tables MRG_MYISAM YES/NO Alias for MERGE -ISAM YES/NO Obsolete table type; Is replaced by MyISAM -MRG_ISAM YES/NO Obsolete table type; Is replaced by MRG_MYISAM -InnoDB YES/NO Supports transactions, row-level locking and foreign keys +ISAM YES/NO Obsolete storage engine, now replaced by MyISAM +MRG_ISAM YES/NO Obsolete storage engine, now replaced by MERGE +InnoDB YES/NO Supports transactions, row-level locking, and foreign keys INNOBASE YES/NO Alias for INNODB BDB YES/NO Supports transactions and page-level locking BERKELEYDB YES/NO Alias for BDB -NDBCLUSTER YES/NO Clustered, fault tolerant memory based tables +NDBCLUSTER YES/NO Clustered, fault-tolerant, memory-based tables NDB YES/NO Alias for NDBCLUSTER EXAMPLE YES/NO Example storage engine ARCHIVE YES/NO Archive storage engine diff --git a/mysql-test/r/rpl_drop.result b/mysql-test/r/rpl_drop.result index ce1f5b6ee81..b83594c9bb1 100644 --- a/mysql-test/r/rpl_drop.result +++ b/mysql-test/r/rpl_drop.result @@ -1,10 +1,10 @@ -slave stop; +stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; +start slave; drop table if exists t1, t2; create table t1 (a int); drop table t1, t2; -Unknown table 't2' +ERROR 42S02: Unknown table 't2' diff --git a/mysql-test/r/subselect2.result b/mysql-test/r/subselect2.result index c2780a08d36..b04fec26c6f 100644 --- a/mysql-test/r/subselect2.result +++ b/mysql-test/r/subselect2.result @@ -120,9 +120,9 @@ DOCID DOCNAME DOCTYPEID FOLDERID AUTHOR CREATED TITLE SUBTITLE DOCABSTRACT PUBLI c373e9f5ad07993f3859444553544200 Last Discussion c373e9f5ad079174ff17444553544200 c373e9f5ad0796c0eca4444553544200 Goldilocks 2003-06-09 11:21:06 Title: Last Discussion NULL Setting new abstract and keeping doc checked out 2003-06-09 10:51:26 2003-06-09 10:51:26 NULL NULL NULL 03eea05112b845949f3fd03278b5fe43 2003-06-09 11:21:06 admin 0 NULL Discussion NULL NULL EXPLAIN SELECT t2.*, t4.DOCTYPENAME, t1.CONTENTSIZE,t1.MIMETYPE FROM t2 INNER JOIN t4 ON t2.DOCTYPEID = t4.DOCTYPEID LEFT OUTER JOIN t1 ON t2.DOCID = t1.DOCID WHERE t2.FOLDERID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t3.FOLDERNAME = 'Level1') AND t3.FOLDERNAME = 'Level2') AND t3.FOLDERNAME = 'Level3') AND t3.FOLDERNAME = 'CopiedFolder') AND t3.FOLDERNAME = 'Movie Reviews') AND t2.DOCNAME = 'Last Discussion'; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t2 ALL DDOCTYPEID_IDX NULL NULL NULL 10 Using where +1 PRIMARY t1 system PRIMARY NULL NULL NULL 0 const row not found +1 PRIMARY t2 ALL DDOCTYPEID_IDX NULL NULL NULL 9 Using where 1 PRIMARY t4 eq_ref PRIMARY PRIMARY 32 test.t2.DOCTYPEID 1 -1 PRIMARY t1 eq_ref PRIMARY PRIMARY 32 test.t2.DOCID 1 2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 32 func 1 Using index; Using where 3 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 32 func 1 Using index; Using where 4 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 32 func 1 Using index; Using where diff --git a/mysql-test/t/create_select_tmp.test b/mysql-test/t/create_select_tmp.test index 36292abd899..166d32fb17c 100644 --- a/mysql-test/t/create_select_tmp.test +++ b/mysql-test/t/create_select_tmp.test @@ -6,7 +6,9 @@ # inconsistency between binlog and the internal list of temp tables. -- source include/have_innodb.inc +--disable_warnings drop table if exists t1, t2; +--enable_warnings CREATE TABLE t1 ( a int ); INSERT INTO t1 VALUES (1),(2),(1); --error 1062; diff --git a/mysql-test/t/rpl_drop.test b/mysql-test/t/rpl_drop.test index 6fc2500fc97..ab5b608cab6 100644 --- a/mysql-test/t/rpl_drop.test +++ b/mysql-test/t/rpl_drop.test @@ -1,7 +1,9 @@ # Testcase for BUG#4552 (DROP on two tables, one of which does not # exist, must be binlogged with a non-zero error code) source include/master-slave.inc; +--disable_warnings drop table if exists t1, t2; +--enable_warnings create table t1 (a int); --error 1051; drop table t1, t2; From 5f3461838b1b4c7ec07d1f71695ffc0b7b3d2ec0 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 20 Jul 2004 11:13:23 +0200 Subject: [PATCH 30/30] oops, forgot to checkin... --- mysql-test/r/ps_3innodb.result | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 8cba3501a73..b89daca7128 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -572,7 +572,7 @@ def ref 253 1024 0 Y 0 31 63 def rows 8 10 1 N 32801 0 8 def Extra 253 255 44 N 1 31 63 id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t_many_col_types ALL NULL NULL NULL NULL 3 +1 PRIMARY t_many_col_types ALL NULL NULL NULL NULL 2 1 PRIMARY ALL NULL NULL NULL NULL 2 Using where 6 DERIVED t2 ALL NULL NULL NULL NULL 2 5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where @@ -581,7 +581,7 @@ id select_type table type possible_keys key key_len ref rows Extra 2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 ; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t_many_col_types ALL NULL NULL NULL NULL 3 +1 PRIMARY t_many_col_types ALL NULL NULL NULL NULL 2 1 PRIMARY ALL NULL NULL NULL NULL 2 Using where 6 DERIVED t2 ALL NULL NULL NULL NULL 2 5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where @@ -643,7 +643,7 @@ def ref 253 1024 0 Y 0 31 63 def rows 8 10 1 N 32801 0 8 def Extra 253 255 44 N 1 31 63 id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t_many_col_types ALL NULL NULL NULL NULL 3 +1 PRIMARY t_many_col_types ALL NULL NULL NULL NULL 2 1 PRIMARY ALL NULL NULL NULL NULL 2 Using where 6 DERIVED t2 ALL NULL NULL NULL NULL 2 5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where @@ -653,7 +653,7 @@ id select_type table type possible_keys key key_len ref rows Extra execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t_many_col_types ALL NULL NULL NULL NULL 3 +1 PRIMARY t_many_col_types ALL NULL NULL NULL NULL 2 1 PRIMARY ALL NULL NULL NULL NULL 2 Using where 6 DERIVED t2 ALL NULL NULL NULL NULL 2 5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where