From b685909d6a9e928885ee3e8fb266077718660f3e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 15 Nov 2004 14:37:40 +0200 Subject: moved procedure list initialization (BUG#6517) mysql-test/r/subselect.result: Subselect in non-select command just after connection mysql-test/t/subselect.test: Subselect in non-select command just after connection sql/sql_lex.cc: moved procedure initialization sql/sql_parse.cc: moved procedure initialization --- sql/sql_lex.cc | 1 + sql/sql_parse.cc | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 679ffb2140e..b5cb8735875 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -157,6 +157,7 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); lex->sql_command=SQLCOM_END; lex->duplicates= DUP_ERROR; + lex->proc_list.first= 0; } void lex_end(LEX *lex) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7420f9de100..078333c9552 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3940,7 +3940,6 @@ mysql_init_select(LEX *lex) { DBUG_ASSERT(lex->result == 0); lex->exchange= 0; - lex->proc_list.first= 0; } } -- cgit v1.2.1 From dd93baa00da5e27f1a27df5762fe112f777f53c1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 16 Nov 2004 00:16:04 +0200 Subject: fixed joincleunup to avoid double deletin tables, and too earlyfull cleanup in case of EXPLAIN fixed cleunup of TMP_TABLE_PARAM (BUG#6406) mysql-test/r/subselect.result: primary query with temporary table and subquery with groupping mysql-test/t/subselect.test: primary query with temporary table and subquery with groupping sql/sql_class.h: fixed cleunup of TMP_TABLE_PARAM sql/sql_select.cc: uncacheable test made simplier fixed joincleunup to avoid double deletin tables, and too earlyfull cleanup in case of EXPLAIN --- sql/sql_class.h | 2 +- sql/sql_select.cc | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index 312d9de9794..6d77b75d70f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1305,7 +1305,7 @@ public: if (copy_field) /* Fix for Intel compiler */ { delete [] copy_field; - copy_field=0; + save_copy_field= copy_field= 0; } } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9162cd30d63..06731d26073 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -936,7 +936,7 @@ JOIN::optimize() } } - if (select_lex->master_unit()->uncacheable) + if (select_lex->uncacheable) { if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) DBUG_RETURN(-1); @@ -3833,7 +3833,8 @@ JOIN::join_free(bool full) JOIN_TAB *tab,*end; DBUG_ENTER("JOIN::join_free"); - full= full || !select_lex->uncacheable; + full= full || (!select_lex->uncacheable && + !thd->lex->describe); if (table) { @@ -3862,6 +3863,7 @@ JOIN::join_free(bool full) for (tab= join_tab, end= tab+tables; tab != end; tab++) tab->cleanup(); table= 0; + tables= 0; } else { -- cgit v1.2.1 From 70ed3160d97d66da74ab031dde64217d501abd6e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 16 Nov 2004 22:58:02 +0200 Subject: backport Serg's fix of FT interface (BUG#6523) mysql-test/r/subselect.result: subqueries with full text search mysql-test/t/subselect.test: subqueries with full text search sql/ha_myisam.h: backport Serg's fix of FT interface sql/handler.h: backport Serg's fix of FT interface sql/opt_range.h: backport Serg's fix of FT interface sql/sql_select.cc: comment for previous patch --- sql/ha_myisam.h | 1 - sql/handler.h | 1 + sql/opt_range.h | 2 +- sql/sql_select.cc | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index 6fde84d6f6f..972d6b18e19 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -81,7 +81,6 @@ class ha_myisam: public handler int index_first(byte * buf); int index_last(byte * buf); int index_next_same(byte *buf, const byte *key, uint keylen); - int index_end() { ft_handler=NULL; return 0; } int ft_init() { if (!ft_handler) diff --git a/sql/handler.h b/sql/handler.h index 252861e5c37..245defe61e0 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -372,6 +372,7 @@ public: virtual int read_range_next(); int compare_key(key_range *range); virtual int ft_init() { return HA_ERR_WRONG_COMMAND; } + void ft_end() { ft_handler=NULL; } virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key, uint keylen) { return NULL; } diff --git a/sql/opt_range.h b/sql/opt_range.h index 9b2e9e45bac..5a2044a59f4 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -154,7 +154,7 @@ class FT_SELECT: public QUICK_SELECT { public: FT_SELECT(THD *thd, TABLE *table, uint key): QUICK_SELECT (thd, table, key, 1) { init(); } - + ~FT_SELECT() { file->ft_end(); } int init() { return error= file->ft_init(); } int get_next() { return error= file->ft_read(record); } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 06731d26073..5809bd2b7be 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3834,7 +3834,7 @@ JOIN::join_free(bool full) DBUG_ENTER("JOIN::join_free"); full= full || (!select_lex->uncacheable && - !thd->lex->describe); + !thd->lex->describe); // do not cleanup too early on EXPLAIN if (table) { -- cgit v1.2.1 From 8127cea5124e44444370df61f0483c18f8c2dcab Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Nov 2004 22:54:49 +0200 Subject: init values to avoid junk returning in case of null value asking without assigning value (BUG#6806) mysql-test/r/subselect.result: Equal operation under row and empty subquery mysql-test/t/subselect.test: Equal operation under row and empty subquery sql/item.h: init values to avoid junk returning in case of null value asking without assigning value --- sql/item.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item.h b/sql/item.h index ccb0fda1c49..3c4f80e3857 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1127,7 +1127,7 @@ class Item_cache_int: public Item_cache { longlong value; public: - Item_cache_int(): Item_cache() {} + Item_cache_int(): Item_cache(), value(0) {} void store(Item *item); double val() { DBUG_ASSERT(fixed == 1); return (double) value; } @@ -1145,7 +1145,7 @@ class Item_cache_real: public Item_cache { double value; public: - Item_cache_real(): Item_cache() {} + Item_cache_real(): Item_cache(), value(0) {} void store(Item *item); double val() { DBUG_ASSERT(fixed == 1); return value; } @@ -1167,7 +1167,7 @@ class Item_cache_str: public Item_cache char buffer[80]; String *value, value_buff; public: - Item_cache_str(): Item_cache() { } + Item_cache_str(): Item_cache(), value(0) { } void store(Item *item); double val(); -- cgit v1.2.1 From a49025d2c86adefcb61517ff75434479b75b8d02 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 30 Nov 2004 21:41:12 +0200 Subject: now we create temporary join for all queries with subqueries to make correct cleunup of tables and avoid too early unlock (BUG#6841) mysql-test/t/subselect_innodb.test: possible early unlock sql/sql_lex.cc: subqueries presence flag sql/sql_lex.h: subqueries presence flag sql/sql_parse.cc: subqueries presence flag sql/sql_select.cc: removed some too optimistic optimisation, now we create temporary join for all queries with subqueries to make correct cleunup of tables and avoid too early unlock --- sql/sql_lex.cc | 2 +- sql/sql_lex.h | 1 + sql/sql_parse.cc | 1 + sql/sql_select.cc | 3 ++- 4 files changed, 5 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index b5cb8735875..1d9afcc94a4 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -135,7 +135,7 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list); lex->select_lex.options= 0; lex->describe= 0; - lex->derived_tables= FALSE; + lex->subqueries= lex->derived_tables= FALSE; lex->lock_option= TL_READ; lex->found_colon= 0; lex->safe_to_cache_query= 1; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 90c020b3e93..123e855061a 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -619,6 +619,7 @@ typedef struct st_lex bool in_comment, ignore_space, verbose, no_write_to_binlog; bool derived_tables; bool safe_to_cache_query; + bool subqueries; ALTER_INFO alter_info; /* Prepared statements SQL syntax:*/ LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 078333c9552..ad68402aeab 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3955,6 +3955,7 @@ mysql_new_select(LEX *lex, bool move_down) select_lex->init_select(); if (move_down) { + lex->subqueries= TRUE; /* first select_lex of subselect or derived table */ SELECT_LEX_UNIT *unit; if (!(unit= new(lex->thd->mem_root) SELECT_LEX_UNIT())) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5809bd2b7be..ec7ea9091be 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -936,7 +936,7 @@ JOIN::optimize() } } - if (select_lex->uncacheable) + if (thd->lex->subqueries) { if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN)))) DBUG_RETURN(-1); @@ -3834,6 +3834,7 @@ JOIN::join_free(bool full) DBUG_ENTER("JOIN::join_free"); full= full || (!select_lex->uncacheable && + !thd->lex->subqueries && !thd->lex->describe); // do not cleanup too early on EXPLAIN if (table) -- cgit v1.2.1 From 352ad8156cc7bd8dc728715569a3bc350108513e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 30 Nov 2004 22:20:52 +0100 Subject: two-line fix for BUG#6732 "FLUSH TABLES WITH READ LOCK + COMMIT makes next FLUSH...LOCK hang forever" (originally reported as "second run of innobackup hangs forever and can even hang server"). Plus testcase for the bugfix and comments about global read locks. mysql-test/r/flush_block_commit.result: result update mysql-test/t/flush_block_commit.test: testing bugfix (originally: second run of innobackup hangs) sql/lock.cc: When we are in start_waiting_global_read_lock(), if we ourselves have the global read lock, there is nothing to start. This makes a pair with how wait_if_global_read_lock() behaves when we ourselves have the global read lock. Previously, start_waiting_global_read_lock() decremented protect... whereas wait_if_global_read_lock() hadn't incremented it => very wrong => hangs. Descriptive comments on how global read lock works. --- sql/lock.cc | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/lock.cc b/sql/lock.cc index bf0160291f8..c7e6ebfda83 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -665,15 +665,70 @@ static void print_lock_error(int error) /**************************************************************************** Handling of global read locks + Taking the global read lock is TWO steps (2nd step is optional; without + it, COMMIT of existing transactions will be allowed): + lock_global_read_lock() THEN make_global_read_lock_block_commit(). + The global locks are handled through the global variables: global_read_lock + count of threads which have the global read lock (i.e. have completed at + least the first step above) global_read_lock_blocks_commit - waiting_for_read_lock + count of threads which have the global read lock and block + commits (i.e. have completed the second step above) + waiting_for_read_lock + count of threads which want to take a global read lock but cannot protect_against_global_read_lock + count of threads which have set protection against global read lock. + + How blocking of threads by global read lock is achieved: that's + advisory. Any piece of code which should be blocked by global read lock must + be designed like this: + - call to wait_if_global_read_lock(). When this returns 0, no global read + lock is owned; if argument abort_on_refresh was 0, none can be obtained. + - job + - if abort_on_refresh was 0, call to start_waiting_global_read_lock() to + allow other threads to get the global read lock. I.e. removal of the + protection. + (Note: it's a bit like an implementation of rwlock). + + [ I am sorry to mention some SQL syntaxes below I know I shouldn't but found + no better descriptive way ] + + Why does FLUSH TABLES WITH READ LOCK need to block COMMIT: because it's used + to read a non-moving SHOW MASTER STATUS, and a COMMIT writes to the binary + log. + + Why getting the global read lock is two steps and not one. Because FLUSH + TABLES WITH READ LOCK needs to insert one other step between the two: + flushing tables. So the order is + 1) lock_global_read_lock() (prevents any new table write locks, i.e. stalls + all new updates) + 2) close_cached_tables() (the FLUSH TABLES), which will wait for tables + currently opened and being updated to close (so it's possible that there is + a moment where all new updates of server are stalled *and* FLUSH TABLES WITH + READ LOCK is, too). + 3) make_global_read_lock_block_commit(). + If we have merged 1) and 3) into 1), we would have had this deadlock: + imagine thread 1 and 2, in non-autocommit mode, thread 3, and an InnoDB + table t. + thd1: SELECT * FROM t FOR UPDATE; + thd2: UPDATE t SET a=1; # blocked by row-level locks of thd1 + thd3: FLUSH TABLES WITH READ LOCK; # blocked in close_cached_tables() by the + table instance of thd2 + thd1: COMMIT; # blocked by thd3. + thd1 blocks thd2 which blocks thd3 which blocks thd1: deadlock. + + Note that we need to support that one thread does + FLUSH TABLES WITH READ LOCK; and then COMMIT; + (that's what innobackup does, for some good reason). + So in this exceptional case the COMMIT should not be blocked by the FLUSH + TABLES WITH READ LOCK. + + TODO in MySQL 5.x: make_global_read_lock_block_commit() should be + killable. Normally CPU does not spend a long time in this function (COMMITs + are quite fast), but it would still be nice. - Taking the global read lock is TWO steps (2nd step is optional; without - it, COMMIT of existing transactions will be allowed): - lock_global_read_lock() THEN make_global_read_lock_block_commit(). ****************************************************************************/ volatile uint global_read_lock=0; @@ -783,6 +838,8 @@ void start_waiting_global_read_lock(THD *thd) { bool tmp; DBUG_ENTER("start_waiting_global_read_lock"); + if (unlikely(thd->global_read_lock)) + DBUG_VOID_RETURN; (void) pthread_mutex_lock(&LOCK_open); tmp= (!--protect_against_global_read_lock && waiting_for_read_lock); (void) pthread_mutex_unlock(&LOCK_open); -- cgit v1.2.1 From ef13523dbc01c5be7587f62c311d762bbd4c3aed Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2004 11:39:50 +0400 Subject: Bug #6815 SHOW CREATE TABLE hangs after upgrading to 4.1 A test doesn't seem to be possible. --- sql/sql_show.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sql') diff --git a/sql/sql_show.cc b/sql/sql_show.cc index bda490e2916..ff0d943a717 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1169,6 +1169,15 @@ append_identifier(THD *thd, String *packet, const char *name, uint length) { uchar chr= (uchar) *name; length= my_mbcharlen(system_charset_info, chr); + /* + my_mbcharlen can retur 0 on a wrong multibyte + sequence. It is possible when upgrading from 4.0, + and identifier contains some accented characters. + The manual says it does not work. So we'll just + change length to 1 not to hang in the endless loop. + */ + if (!length) + length= 1; if (length == 1 && chr == (uchar) quote_char) packet->append("e_char, 1, system_charset_info); packet->append(name, length, packet->charset()); -- cgit v1.2.1 From 5167b5f0ce57368d99d73e3299e8d891e5fb322a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2004 12:48:43 +0400 Subject: Bug #6379: ENUM values are incorrectly converted - add_field_to_list() now uses String instead of TYPELIB to be able to distinguish literals 'aaa' and hex literals 0xaabbcc. - move some code from add_field_to_list() where we don't know column charset yet, to mysql_prepare_table(), where we do. --- sql/field.h | 1 + sql/mysql_priv.h | 3 +- sql/sql_lex.h | 1 - sql/sql_parse.cc | 99 ++++++++++++--------------------------------- sql/sql_table.cc | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/sql_yacc.yy | 20 +++------- 6 files changed, 155 insertions(+), 89 deletions(-) (limited to 'sql') diff --git a/sql/field.h b/sql/field.h index 8887da1dc0f..bb999222381 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1198,6 +1198,7 @@ public: uint decimals,flags,pack_length; Field::utype unireg_check; TYPELIB *interval; // Which interval to use + List interval_list; CHARSET_INFO *charset; Field::geometry_type geom_type; Field *field; // For alter table diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 3f55a88b262..3a19a903e00 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -688,7 +688,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum enum_field_types type, uint type_modifier, Item *default_value, Item *on_update_value, LEX_STRING *comment, - char *change, TYPELIB *interval,CHARSET_INFO *cs, + char *change, List *interval_list, + CHARSET_INFO *cs, uint uint_geom_type); void store_position_for_column(const char *name); bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc=0); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 90c020b3e93..68a5ac29254 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -592,7 +592,6 @@ typedef struct st_lex List var_list; List param_list; SQL_LIST proc_list, auxilliary_table_list, save_list; - TYPELIB *interval; create_field *last_field; char *savepoint_name; // Transaction savepoint id udf_func udf; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e066e447345..990e52d05ce 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4115,31 +4115,6 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) #endif -/* - Calculate interval lengths. - Strip trailing spaces from all strings. - After this function call: - - ENUM uses max_length - - SET uses tot_length. -*/ -void calculate_interval_lengths(THD *thd, TYPELIB *interval, - uint32 *max_length, uint32 *tot_length) -{ - const char **pos; - uint *len; - CHARSET_INFO *cs= thd->variables.character_set_client; - *max_length= *tot_length= 0; - for (pos= interval->type_names, len= interval->type_lengths; - *pos ; pos++, len++) - { - *len= (uint) strip_sp((char*) *pos); - uint length= cs->cset->numchars(cs, *pos, *pos + *len); - *tot_length+= length; - set_if_bigger(*max_length, (uint32)length); - } -} - - /***************************************************************************** ** Store field definition for create ** Return 0 if ok @@ -4150,7 +4125,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, uint type_modifier, Item *default_value, Item *on_update_value, LEX_STRING *comment, - char *change, TYPELIB *interval, CHARSET_INFO *cs, + char *change, + List *interval_list, CHARSET_INFO *cs, uint uint_geom_type) { register create_field *new_field; @@ -4445,62 +4421,39 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, break; case FIELD_TYPE_SET: { - if (interval->count > sizeof(longlong)*8) + if (interval_list->elements > sizeof(longlong)*8) { - net_printf(thd,ER_TOO_BIG_SET,field_name); /* purecov: inspected */ - DBUG_RETURN(1); /* purecov: inspected */ + net_printf(thd,ER_TOO_BIG_SET,field_name); /* purecov: inspected */ + DBUG_RETURN(1); /* purecov: inspected */ } - new_field->pack_length=(interval->count+7)/8; + new_field->pack_length= (interval_list->elements + 7) / 8; if (new_field->pack_length > 4) - new_field->pack_length=8; - new_field->interval=interval; - uint32 dummy_max_length; - calculate_interval_lengths(thd, interval, - &dummy_max_length, &new_field->length); - new_field->length+= (interval->count - 1); - set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); - if (default_value) - { - char *not_used; - uint not_used2; - bool not_used3; - - thd->cuted_fields=0; - String str,*res; - res=default_value->val_str(&str); - (void) find_set(interval, res->ptr(), res->length(), - &my_charset_bin, - ¬_used, ¬_used2, ¬_used3); - if (thd->cuted_fields) - { - net_printf(thd,ER_INVALID_DEFAULT,field_name); - DBUG_RETURN(1); - } - } + new_field->pack_length=8; + + List_iterator it(*interval_list); + String *tmp; + while ((tmp= it++)) + new_field->interval_list.push_back(tmp); + /* + Set fake length to 1 to pass the below conditions. + Real length will be set in mysql_prepare_table() + when we know the character set of the column + */ + new_field->length= 1; } break; case FIELD_TYPE_ENUM: { - new_field->interval=interval; - new_field->pack_length=interval->count < 256 ? 1 : 2; // Should be safe + // Should be safe + new_field->pack_length= interval_list->elements < 256 ? 1 : 2; - uint32 dummy_tot_length; - calculate_interval_lengths(thd, interval, - &new_field->length, &dummy_tot_length); - set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); - if (default_value) - { - String str,*res; - res=default_value->val_str(&str); - res->strip_sp(); - if (!find_type(interval, res->ptr(), res->length(), 0)) - { - net_printf(thd,ER_INVALID_DEFAULT,field_name); - DBUG_RETURN(1); - } - } - break; + List_iterator it(*interval_list); + String *tmp; + while ((tmp= it++)) + new_field->interval_list.push_back(tmp); + new_field->length= 1; // See comment for FIELD_TYPE_SET above. } + break; } if ((new_field->length > MAX_FIELD_CHARLENGTH && type != FIELD_TYPE_SET && diff --git a/sql/sql_table.cc b/sql/sql_table.cc index eedd9388877..a304e821ecd 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -392,6 +392,41 @@ void check_duplicates_in_interval(const char *set_or_name, } } + +/* + Check TYPELIB (set or enum) max and total lengths + + SYNOPSIS + calculate_interval_lengths() + cs charset+collation pair of the interval + typelib list of values for the column + max_length length of the longest item + tot_length sum of the item lengths + + DESCRIPTION + After this function call: + - ENUM uses max_length + - SET uses tot_length. + + RETURN VALUES + void +*/ +void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval, + uint32 *max_length, uint32 *tot_length) +{ + const char **pos; + uint *len; + *max_length= *tot_length= 0; + for (pos= interval->type_names, len= interval->type_lengths; + *pos ; pos++, len++) + { + uint length= cs->cset->numchars(cs, *pos, *pos + *len); + *tot_length+= length; + set_if_bigger(*max_length, (uint32)length); + } +} + + /* Preparation for table creation @@ -455,6 +490,91 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, DBUG_RETURN(-1); } + if ((sql_field->sql_type == FIELD_TYPE_SET || + sql_field->sql_type == FIELD_TYPE_ENUM) && !sql_field->interval) + { + uint32 dummy; + CHARSET_INFO *cs= sql_field->charset; + TYPELIB *interval; + + /* + Create typelib from interval_list, and if necessary + convert strings from client character set to the + column character set. + */ + + interval= sql_field->interval= typelib(sql_field->interval_list); + List_iterator it(sql_field->interval_list); + String conv, *tmp; + for (uint i= 0; (tmp= it++); i++) + { + if (String::needs_conversion(tmp->length(), tmp->charset(), cs, &dummy)) + { + uint cnv_errs; + conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs); + char *buf= (char*) sql_alloc(conv.length()+1); + memcpy(buf, conv.ptr(), conv.length()); + buf[conv.length()]= '\0'; + interval->type_names[i]= buf; + interval->type_lengths[i]= conv.length(); + } + + // Strip trailing spaces. + uint lengthsp= cs->cset->lengthsp(cs, interval->type_names[i], + interval->type_lengths[i]); + interval->type_lengths[i]= lengthsp; + ((uchar *)interval->type_names[i])[lengthsp]= '\0'; + } + sql_field->interval_list.empty(); // Don't need interval_list anymore + + + /* + Convert the default value from client character + set into the column character set if necessary. + */ + if (sql_field->def) + { + sql_field->def= + sql_field->def->safe_charset_converter(cs); + } + + if (sql_field->sql_type == FIELD_TYPE_SET) + { + if (sql_field->def) + { + char *not_used; + uint not_used2; + bool not_found= 0; + String str, *def= sql_field->def->val_str(&str); + def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); + (void) find_set(interval, def->ptr(), def->length(), + cs, ¬_used, ¬_used2, ¬_found); + if (not_found) + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } + } + calculate_interval_lengths(cs, interval, &dummy, &sql_field->length); + sql_field->length+= (interval->count - 1); + } + else /* FIELD_TYPE_ENUM */ + { + if (sql_field->def) + { + String str, *def= sql_field->def->val_str(&str); + def->length(cs->cset->lengthsp(cs, def->ptr(), def->length())); + if (!find_type2(interval, def->ptr(), def->length(), cs)) + { + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } + } + calculate_interval_lengths(cs, interval, &sql_field->length, &dummy); + } + set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1); + } + sql_field->create_length_to_internal_length(); /* Don't pack keys in old tables if the user has requested this */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8cbfaf3f99b..49e567ab54b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1361,7 +1361,7 @@ field_spec: field_ident { LEX *lex=Lex; - lex->length=lex->dec=0; lex->type=0; lex->interval=0; + lex->length=lex->dec=0; lex->type=0; lex->default_value= lex->on_update_value= 0; lex->comment=0; lex->charset=NULL; @@ -1374,7 +1374,7 @@ field_spec: lex->length,lex->dec,lex->type, lex->default_value, lex->on_update_value, lex->comment, - lex->change,lex->interval,lex->charset, + lex->change,&lex->interval_list,lex->charset, lex->uint_geom_type)) YYABORT; }; @@ -1471,17 +1471,9 @@ type: | FIXED_SYM float_options field_options { $$=FIELD_TYPE_DECIMAL;} | ENUM {Lex->interval_list.empty();} '(' string_list ')' opt_binary - { - LEX *lex=Lex; - lex->interval=typelib(lex->interval_list); - $$=FIELD_TYPE_ENUM; - } + { $$=FIELD_TYPE_ENUM; } | SET { Lex->interval_list.empty();} '(' string_list ')' opt_binary - { - LEX *lex=Lex; - lex->interval=typelib(lex->interval_list); - $$=FIELD_TYPE_SET; - } + { $$=FIELD_TYPE_SET; } | LONG_SYM opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } | SERIAL_SYM { @@ -1925,7 +1917,7 @@ alter_list_item: | MODIFY_SYM opt_column field_ident { LEX *lex=Lex; - lex->length=lex->dec=0; lex->type=0; lex->interval=0; + lex->length=lex->dec=0; lex->type=0; lex->default_value= lex->on_update_value= 0; lex->comment=0; lex->charset= NULL; @@ -1940,7 +1932,7 @@ alter_list_item: lex->length,lex->dec,lex->type, lex->default_value, lex->on_update_value, lex->comment, - $3.str, lex->interval, lex->charset, + $3.str, &lex->interval_list, lex->charset, lex->uint_geom_type)) YYABORT; } -- cgit v1.2.1 From 491a3d90a99c3849c220592b4f8ff29de8484de9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2004 13:34:30 +0400 Subject: Fixes (bug #6932: 'revoke all privileges...' doesn't remove all proper columns from columns_priv bug #6933: error in the tests/grant.pl test). mysql-test/r/grant.result: A fix (bug #6932: 'revoke all privileges...' doesn't remove all proper columns from columns_priv). mysql-test/t/grant.test: A fix (bug #6932: 'revoke all privileges...' doesn't remove all proper columns from columns_priv). sql/sql_acl.cc: A fix (bug #6932: 'revoke all privileges...' doesn't remove all proper columns from columns_priv). The problem is that we use whole key length (including 'Column_name' keypart) during scanning the 'columns_priv' table in case of revoke_grant. tests/grant.pl: A fix (bug #6933: error in the tests/grant.pl test). --- sql/sql_acl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d6f52fed1d2..f1698dcc911 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2035,7 +2035,7 @@ static int replace_column_table(GRANT_TABLE *g_t, { table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read(table->record[0], (byte*) table->field[0]->ptr, - table->key_info[0].key_length, + key_length, HA_READ_KEY_EXACT)) goto end; -- cgit v1.2.1 From d0a47dbf72e4a6dee4d061c16183c933ff35e8f6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2004 12:40:25 +0200 Subject: mysqld.cc: innodb_autoextend_increment: set a maximum limit of 1000 (Bug #6904) sql/mysqld.cc: innodb_autoextend_increment: set a maximum limit of 1000 (Bug #6904) --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index baab3017623..da834080bc0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4801,7 +4801,7 @@ replicating a LOAD DATA INFILE command.", "Data file autoextend increment in megabytes", (gptr*) &srv_auto_extend_increment, (gptr*) &srv_auto_extend_increment, - 0, GET_LONG, REQUIRED_ARG, 8L, 1L, ~0L, 0, 1L, 0}, + 0, GET_LONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0}, {"innodb_buffer_pool_awe_mem_mb", OPT_INNODB_BUFFER_POOL_AWE_MEM_MB, "If Windows AWE is used, the size of InnoDB buffer pool allocated from the AWE memory.", (gptr*) &innobase_buffer_pool_awe_mem_mb, (gptr*) &innobase_buffer_pool_awe_mem_mb, 0, -- cgit v1.2.1 From d3c5c4997ca71610abf7e94b0c66f27278e3341e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2004 16:08:17 +0400 Subject: Fixes to make mysql-test-run --embedded-server working mysql-test/mysql-test-run.sh: Tests that can't be fixed now showed in the ignore-list mysql-test/r/query_cache.result.es: test result renewed mysql-test/r/select.result.es: test result renewed mysql-test/r/type_blob.result.es: test result renewed mysql-test/r/type_float.result.es: test result renewed sql/sql_prepare.cc: time values sending fixed tests/client_test.c: that doesnt work in embedded server BitKeeper/etc/ignore: Added libmysqld/ha_archive.cc libmysqld/ha_example.cc libmysqld/ha_tina.cc to the ignore list --- sql/sql_prepare.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index a790e6fe9d8..637bb48b2cf 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -427,8 +427,17 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len) #else/*!EMBEDDED_LIBRARY*/ void set_param_time(Item_param *param, uchar **pos, ulong len) { - MYSQL_TIME *to= (MYSQL_TIME*)*pos; - param->set_time(to, MYSQL_TIMESTAMP_TIME, + MYSQL_TIME tm= *((MYSQL_TIME*)*pos); + tm.hour+= tm.day * 24; + tm.day= tm.year= tm.month= 0; + if (tm.hour > 838) + { + /* TODO: add warning 'Data truncated' here */ + tm.hour= 838; + tm.minute= 59; + tm.second= 59; + } + param->set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } -- cgit v1.2.1 From 93cf297fcb932aaaf1c006d7066ec453c9a907cb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2004 14:43:51 +0200 Subject: Cleanups during review stage Added auto-correct of field length for enum/set tables for ALTER TABLE This is becasue of a bug in previous MySQL 4.1 versions where the length for enum/set was set incorrectly after ALTER TABLE mysql-test/r/rpl_start_stop_slave.result: Fixed wrong test mysql-test/r/type_enum.result: Added test for wrong enum/set length after alter table mysql-test/t/ps.test: removed empty line mysql-test/t/type_enum.test: Added test for wrong enum/set length after alter table sql/field.cc: Added auto-correct of field length for enum/set tables. This is becasue of a bug in previous MySQL 4.1 versions where the length for enum/set was set incorrectly after ALTER TABLE sql/item_cmpfunc.cc: Simple optimization sql/mysql_priv.h: Made local function global sql/set_var.cc: Simple cleanup sql/sql_table.cc: Simple cleanups & optimizations --- sql/field.cc | 60 +++++++++++++++++++++++++++++++++++++---------------- sql/item_cmpfunc.cc | 12 +++++------ sql/mysql_priv.h | 2 ++ sql/set_var.cc | 9 ++++---- sql/sql_table.cc | 14 ++++--------- 5 files changed, 58 insertions(+), 39 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 72c27b6adf9..eee7f6f1684 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5842,25 +5842,47 @@ bool Field_num::eq_def(Field *field) void create_field::create_length_to_internal_length(void) { - switch (sql_type) + switch (sql_type) { + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_STRING: + length*= charset->mbmaxlen; + pack_length= calc_pack_length(sql_type == FIELD_TYPE_VAR_STRING ? + FIELD_TYPE_STRING : sql_type, length); + break; +#ifdef CORRECT_CODE_BUT_CANT_YET_BE_USED + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + length*= charset->mbmaxlen; + break; +#else + /* + Because of a bug in MySQL 4.1 where length was extended for ENUM and SET + fields for every ALTER TABLE, we have to recalculate lengths here + */ + case MYSQL_TYPE_ENUM: { - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - length*= charset->mbmaxlen; - pack_length= calc_pack_length(sql_type == FIELD_TYPE_VAR_STRING ? - FIELD_TYPE_STRING : sql_type, length); - break; - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - length*= charset->mbmaxlen; - break; - default: - /* do nothing */ - break; + uint32 tot_length, max_length; + calculate_interval_lengths(current_thd, interval, + &max_length, &tot_length); + length= max_length * charset->mbmaxlen; + break; + } + case MYSQL_TYPE_SET: + { + uint32 tot_length, max_length; + calculate_interval_lengths(current_thd, interval, + &max_length, &tot_length); + length= (tot_length + (interval->count - 1)) * charset->mbmaxlen; + break; + } +#endif + default: + /* do nothing */ + break; } } @@ -6085,6 +6107,8 @@ create_field::create_field(Field *old_field,Field *orig_field) } length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; // QQ: Probably not needed break; + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4970517de87..c7481192be8 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2365,10 +2365,10 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } int error; if ((error= regcomp(&preg,res->c_ptr(), - ((cmp_collation.collation->state & MY_CS_BINSORT) || - (cmp_collation.collation->state & MY_CS_CSSORT)) ? + ((cmp_collation.collation->state & + (MY_CS_BINSORT | MY_CS_CSSORT)) ? REG_EXTENDED | REG_NOSUB : - REG_EXTENDED | REG_NOSUB | REG_ICASE, + REG_EXTENDED | REG_NOSUB | REG_ICASE), cmp_collation.collation))) { (void) regerror(error,&preg,buff,sizeof(buff)); @@ -2417,10 +2417,10 @@ longlong Item_func_regex::val_int() regex_compiled=0; } if (regcomp(&preg,res2->c_ptr(), - ((cmp_collation.collation->state & MY_CS_BINSORT) || - (cmp_collation.collation->state & MY_CS_CSSORT)) ? + ((cmp_collation.collation->state & + (MY_CS_BINSORT | MY_CS_CSSORT)) ? REG_EXTENDED | REG_NOSUB : - REG_EXTENDED | REG_NOSUB | REG_ICASE, + REG_EXTENDED | REG_NOSUB | REG_ICASE), cmp_collation.collation)) { null_value=1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 3f55a88b262..331dc43f9ad 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -370,6 +370,8 @@ int insert_precheck(THD *thd, TABLE_LIST *tables); int create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table); Item *negate_expression(THD *thd, Item *expr); +void calculate_interval_lengths(THD *thd, TYPELIB *interval, + uint *max_length, uint *tot_length); #include "sql_class.h" #include "opt_range.h" diff --git a/sql/set_var.cc b/sql/set_var.cc index 2031ac15412..79be4dc1c46 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2725,24 +2725,23 @@ sys_var *find_sys_var(const char *str, uint length) int sql_set_variables(THD *thd, List *var_list) { - int error= 0; + int error; List_iterator_fast it(*var_list); DBUG_ENTER("sql_set_variables"); set_var_base *var; while ((var=it++)) { - if ((error=var->check(thd))) + if ((error= var->check(thd))) goto err; } - if (!thd->net.report_error) + if (!(error= test(thd->net.report_error))) { it.rewind(); while ((var= it++)) error|= var->update(thd); // Returns 0, -1 or 1 } - else - error= 1; + err: free_underlaid_joins(thd, &thd->lex->select_lex); DBUG_RETURN(error); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index eedd9388877..2260877fc05 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -814,8 +814,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, DBUG_RETURN(-1); } } - else - if (key_info->algorithm == HA_KEY_ALG_RTREE) + else if (key_info->algorithm == HA_KEY_ALG_RTREE) { #ifdef HAVE_RTREE_KEYS if ((key_info->key_parts & 1) == 1) @@ -839,6 +838,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, CHARSET_INFO *ft_key_charset=0; // for FULLTEXT for (uint column_nr=0 ; (column=cols++) ; column_nr++) { + key_part_spec *dup_column; + it.rewind(); field=0; while ((sql_field=it++) && @@ -853,9 +854,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, column->field_name); DBUG_RETURN(-1); } - for (uint dup_nr= 0; dup_nr < column_nr; dup_nr++) + while ((dup_column= cols2++) != column) { - key_part_spec *dup_column= cols2++; if (!my_strcasecmp(system_charset_info, column->field_name, dup_column->field_name)) { @@ -866,12 +866,6 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } } cols2.rewind(); - /* for fulltext keys keyseg length is 1 for blobs (it's ignored in - ft code anyway, and 0 (set to column width later) for char's. - it has to be correct col width for char's, as char data are not - prefixed with length (unlike blobs, where ft code takes data length - from a data prefix, ignoring column->length). - */ if (key->type == Key::FULLTEXT) { if ((sql_field->sql_type != FIELD_TYPE_STRING && -- cgit v1.2.1 From 374252c6860bfeab1efcd44078c0e203d21d676d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2004 15:14:01 +0200 Subject: merge (new code fixed the ALTER TABLE problem) --- sql/field.cc | 23 ----------------------- sql/mysql_priv.h | 2 -- 2 files changed, 25 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index b9c9b269070..90203d1935d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5853,33 +5853,10 @@ void create_field::create_length_to_internal_length(void) pack_length= calc_pack_length(sql_type == FIELD_TYPE_VAR_STRING ? FIELD_TYPE_STRING : sql_type, length); break; -#ifdef CORRECT_CODE_BUT_CANT_YET_BE_USED case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: length*= charset->mbmaxlen; break; -#else - /* - Because of a bug in MySQL 4.1 where length was extended for ENUM and SET - fields for every ALTER TABLE, we have to recalculate lengths here - */ - case MYSQL_TYPE_ENUM: - { - uint32 tot_length, max_length; - calculate_interval_lengths(current_thd, interval, - &max_length, &tot_length); - length= max_length * charset->mbmaxlen; - break; - } - case MYSQL_TYPE_SET: - { - uint32 tot_length, max_length; - calculate_interval_lengths(current_thd, interval, - &max_length, &tot_length); - length= (tot_length + (interval->count - 1)) * charset->mbmaxlen; - break; - } -#endif default: /* do nothing */ break; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b4f19a54de2..3a19a903e00 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -370,8 +370,6 @@ int insert_precheck(THD *thd, TABLE_LIST *tables); int create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table); Item *negate_expression(THD *thd, Item *expr); -void calculate_interval_lengths(THD *thd, TYPELIB *interval, - uint *max_length, uint *tot_length); #include "sql_class.h" #include "opt_range.h" -- cgit v1.2.1 From d1964f416324cd154b436671f370d71bf29b96bd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2004 20:53:54 +0100 Subject: compatibility fix --- sql/item_func.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item_func.cc b/sql/item_func.cc index 32841ba447b..5ed543efbc7 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -171,7 +171,7 @@ bool Item_func::agg_arg_charsets(DTCollation &coll, for (arg= args, last= args + nargs; arg < last; arg++) { Item* conv; - uint dummy_offset; + uint32 dummy_offset; if (!String::needs_conversion(0, coll.collation, (*arg)->collation.collation, &dummy_offset)) -- cgit v1.2.1 From 9286d1c1452d53dd36c94fbe94a3f99be7b1dfb2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Dec 2004 00:05:11 +0100 Subject: Prevent adding 'CREATE TABLE .. SELECT' query to the binary log when the insertion of new records partially failed. It would get logged because of the logic to log a partially-failed 'INSERT ... SELECT' (which can't be rolled back in non-transactional tables), but 'CREATE TABLE ... SELECT' is always rolled back on failure, even for non-transactional tables. (Bug #6682) (Original fix reimplemented after review by Serg and Guilhem.) mysql-test/t/insert_select.test: Add test case for Bug #6682 mysql-test/r/insert_select.result: Add results for test case for Bug #6682 sql/sql_table.cc: moved tmp_disable_binlog() and reenable_binlog macros to sql/sql_class.h sql/sql_insert.cc: disable binlog during call to super's ::send_error in select_create class sql/sql_class.h: add select_create::send_error() BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/sql_class.h | 10 ++++++++++ sql/sql_insert.cc | 13 +++++++++++++ sql/sql_table.cc | 8 -------- 3 files changed, 23 insertions(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index 4250ebdd568..17d371d3dc0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -637,6 +637,15 @@ public: #endif }; +# define tmp_disable_binlog(A) \ + ulong save_options= (A)->options, save_master_access= (A)->master_access; \ + (A)->options&= ~OPTION_BIN_LOG; \ + (A)->master_access|= SUPER_ACL; /* unneeded in 4.1 */ + +#define reenable_binlog(A) \ + (A)->options= save_options; \ + (A)->master_access= save_master_access; + /* Flags for the THD::system_thread (bitmap) variable */ #define SYSTEM_THREAD_DELAYED_INSERT 1 #define SYSTEM_THREAD_SLAVE_IO 2 @@ -781,6 +790,7 @@ public: {} int prepare(List &list); bool send_data(List &values); + void send_error(uint errcode,const char *err); bool send_eof(); void abort(); }; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 8912c1faf2a..0c62a9af7ba 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1505,6 +1505,19 @@ bool select_create::send_data(List &values) return 0; } + +void select_create::send_error(uint errcode,const char *err) +{ + /* + Disable binlog, because we "roll back" partial inserts in ::abort + by removing the table, even for non-transactional tables. + */ + tmp_disable_binlog(thd); + select_insert::send_error(errcode, err); + reenable_binlog(thd); +} + + extern HASH open_cache; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1e5237b1428..33bdd992efb 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -31,14 +31,6 @@ #endif #include "sql_acl.h" // for SUPER_ACL -# define tmp_disable_binlog(A) \ - ulong save_options= (A)->options, save_master_access= (A)->master_access; \ - (A)->options&= ~OPTION_BIN_LOG; \ - (A)->master_access|= SUPER_ACL; /* unneeded in 4.1 */ - -#define reenable_binlog(A) \ - (A)->options= save_options; \ - (A)->master_access= save_master_access; extern HASH open_cache; static const char *primary_key_name="PRIMARY"; -- cgit v1.2.1 From 8948b7450fa543ef14f29b6087fd70ccfa640972 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Dec 2004 02:44:33 +0100 Subject: Manual fixes to merge of fix for Bug #6682 to 4.1. sql/sql_class.h: update tmp_disable_binlog() and reenable_binlog() macros mysql-test/r/insert_select.result: Handle results that differ from 4.0 to 4.1 --- sql/sql_class.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index 4e695701310..eaddca7b7d8 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1092,14 +1092,11 @@ public: void end_statement(); }; -# define tmp_disable_binlog(A) \ - ulong save_options= (A)->options, save_master_access= (A)->master_access; \ - (A)->options&= ~OPTION_BIN_LOG; \ - (A)->master_access|= SUPER_ACL; /* unneeded in 4.1 */ - -#define reenable_binlog(A) \ - (A)->options= save_options; \ - (A)->master_access= save_master_access; +#define tmp_disable_binlog(A) \ + ulong save_options= (A)->options; \ + (A)->options&= ~OPTION_BIN_LOG; + +#define reenable_binlog(A) (A)->options= save_options; /* Flags for the THD::system_thread (bitmap) variable */ #define SYSTEM_THREAD_DELAYED_INSERT 1 -- cgit v1.2.1 From 220acb328e8f4e46fd16b60af6c5a23852e4feef Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Dec 2004 12:13:51 +0100 Subject: Bug#6391 (binlog-do-db rules ignored) CREATE DATABASE statement used the current database instead of the database created when checking conditions for replication. CREATE/DROP/ALTER DATABASE statements are now replicated based on the manipulated database. mysql-test/t/rpl_until.test: Longer sleep to allow slave to stop. mysql-test/t/rpl_charset.test: Position change in binary file. mysql-test/r/drop_temp_table.result: Position change in binlog. mysql-test/r/rpl_loaddata_rule_m.result: Position change in binlog. mysql-test/r/rpl_charset.result: Position change in binlog. sql/log_event.h: Added new flag and parameter to suppress generation of USE statements. sql/log_event.cc: Added parameter and code to suppress generation of USE statements. sql/sql_db.cc: Suppress generation of USE before CREATE/ALTER/DROP DATABASE statements. sql/log.cc: Query_log_event have new extra parameter. sql/sql_table.cc: Query_log_event have new extra parameter. sql/sql_base.cc: Query_log_event have new extra parameter. sql/sql_update.cc: Query_log_event have new extra parameter. sql/sql_insert.cc: Query_log_event have new extra parameter. sql/sql_rename.cc: Query_log_event have new extra parameter. sql/sql_delete.cc: Query_log_event have new extra parameter. sql/sql_acl.cc: Query_log_event have new extra parameter. sql/handler.cc: Query_log_event have new extra parameter. sql/item_func.cc: Query_log_event have new extra parameter. sql/sql_parse.cc: Query_log_event have new extra parameter. --- sql/handler.cc | 4 ++-- sql/item_func.cc | 2 +- sql/log.cc | 14 +++++++------- sql/log_event.cc | 30 ++++++++++++++++++++---------- sql/log_event.h | 20 +++++++++++++++++--- sql/sql_acl.cc | 2 +- sql/sql_base.cc | 4 ++-- sql/sql_db.cc | 44 +++++++++++++++++++++++++++++++++++++++++--- sql/sql_delete.cc | 6 +++--- sql/sql_insert.cc | 8 ++++---- sql/sql_parse.cc | 16 ++++++++-------- sql/sql_rename.cc | 2 +- sql/sql_table.cc | 17 ++++++++++------- sql/sql_update.cc | 4 ++-- 14 files changed, 119 insertions(+), 54 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index 5dae7950390..d2844f3e09b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -723,7 +723,7 @@ int ha_rollback_to_savepoint(THD *thd, char *savepoint_name) if (unlikely((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && my_b_tell(&thd->transaction.trans_log))) { - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE); + Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); if (mysql_bin_log.write(&qinfo)) error= 1; } @@ -761,7 +761,7 @@ int ha_savepoint(THD *thd, char *savepoint_name) innobase_savepoint(thd,savepoint_name, my_b_tell(&thd->transaction.trans_log)); #endif - Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE); + Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE); if (mysql_bin_log.write(&qinfo)) error= 1; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 3fb5bcd01c6..b0ea9a52fb6 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2007,7 +2007,7 @@ void item_user_lock_release(User_level_lock *ull) tmp.copy(command, strlen(command), tmp.charset()); tmp.append(ull->key,ull->key_length); tmp.append("\")", 2); - Query_log_event qev(current_thd, tmp.ptr(), tmp.length(),1); + Query_log_event qev(current_thd, tmp.ptr(), tmp.length(),1, FALSE); qev.error_code=0; // this query is always safe to run on slave mysql_bin_log.write(&qev); } diff --git a/sql/log.cc b/sql/log.cc index 460910fcee8..6c3ba68165c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1274,7 +1274,7 @@ bool MYSQL_LOG::write(Log_event* event_info) (local_db && !db_ok(local_db, binlog_do_db, binlog_ignore_db))) { VOID(pthread_mutex_unlock(&LOCK_log)); - DBUG_PRINT("error",("!db_ok")); + DBUG_PRINT("error",("!db_ok('%s')", local_db)); DBUG_RETURN(0); } #endif /* HAVE_REPLICATION */ @@ -1317,7 +1317,7 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", (uint) thd->variables.collation_connection->number, (uint) thd->variables.collation_database->number, (uint) thd->variables.collation_server->number); - Query_log_event e(thd, buf, written, 0); + Query_log_event e(thd, buf, written, 0, FALSE); e.set_log_pos(this); if (e.write(file)) goto err; @@ -1333,7 +1333,7 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", char *buf_end= strxmov(buf, "SET ONE_SHOT TIME_ZONE='", thd->variables.time_zone->get_name()->ptr(), "'", NullS); - Query_log_event e(thd, buf, buf_end - buf, 0); + Query_log_event e(thd, buf, buf_end - buf, 0, FALSE); e.set_log_pos(this); if (e.write(file)) goto err; @@ -1402,7 +1402,7 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) { - Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=0", 24, 0); + Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=0", 24, 0, FALSE); e.set_log_pos(this); if (e.write(file)) goto err; @@ -1421,7 +1421,7 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", { if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) { - Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0); + Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0, FALSE); e.set_log_pos(this); if (e.write(file)) goto err; @@ -1597,7 +1597,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) we will add the "COMMIT mark and write the buffer to the binlog. */ { - Query_log_event qinfo(thd, "BEGIN", 5, TRUE); + Query_log_event qinfo(thd, "BEGIN", 5, TRUE, FALSE); /* Imagine this is rollback due to net timeout, after all statements of the transaction succeeded. Then we want a zero-error code in BEGIN. @@ -1638,7 +1638,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) Query_log_event qinfo(thd, commit_or_rollback ? "COMMIT" : "ROLLBACK", commit_or_rollback ? 6 : 8, - TRUE); + TRUE, FALSE); qinfo.error_code= 0; qinfo.set_log_pos(this); if (qinfo.write(&log_file) || flush_io_cache(&log_file) || diff --git a/sql/log_event.cc b/sql/log_event.cc index 2fdc89504d7..7a4d14d101a 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -780,7 +780,8 @@ void Query_log_event::pack_info(Protocol *protocol) if (!(buf= my_malloc(9 + db_len + q_len, MYF(MY_WME)))) return; pos= buf; - if (db && db_len) + if (!(flags & LOG_EVENT_SUPPRESS_USE_F) + && db && db_len) { pos= strmov(buf, "use `"); memcpy(pos, db, db_len); @@ -872,9 +873,12 @@ int Query_log_event::write_data(IO_CACHE* file) #ifndef MYSQL_CLIENT Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, - ulong query_length, bool using_trans) - :Log_event(thd_arg, !thd_arg->tmp_table_used ? - 0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans), + ulong query_length, bool using_trans, + bool suppress_use) + :Log_event(thd_arg, + ((thd_arg->tmp_table_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0) + | (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0)), + using_trans), data_buf(0), query(query_arg), db(thd_arg->db), q_len((uint32) query_length), error_code(thd_arg->killed ? @@ -949,14 +953,20 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) bool different_db= 1; - if (db && last_db) + if (!(flags & LOG_EVENT_SUPPRESS_USE_F)) { - if (different_db= memcmp(last_db, db, db_len + 1)) - memcpy(last_db, db, db_len + 1); + if (db && last_db) + { + if (different_db= memcmp(last_db, db, db_len + 1)) + memcpy(last_db, db, db_len + 1); + } + + if (db && db[0] && different_db) + { + fprintf(file, "use %s;\n", db); + } } - - if (db && db[0] && different_db) - fprintf(file, "use %s;\n", db); + end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10); *end++=';'; *end++='\n'; diff --git a/sql/log_event.h b/sql/log_event.h index 1606659e21e..8a2334e8574 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -264,6 +264,19 @@ struct sql_ex_info */ #define LOG_EVENT_THREAD_SPECIFIC_F 0x4 +/* + Suppress the generation of 'USE' statements before the actual + statement. This flag should be set for any events that does not need + the current database set to function correctly. Most notable cases + are 'CREATE DATABASE' and 'DROP DATABASE'. + + This flags should only be used in exceptional circumstances, since + it introduce a significant change in behaviour regarding the + replication logic together with the flags --binlog-do-db and + --replicated-do-db. + */ +#define LOG_EVENT_SUPPRESS_USE_F 0x8 + enum Log_event_type { UNKNOWN_EVENT= 0, START_EVENT= 1, QUERY_EVENT= 2, STOP_EVENT= 3, @@ -331,8 +344,9 @@ public: /* Some 16 flags. Only one is really used now; look above for - LOG_EVENT_TIME_F, LOG_EVENT_FORCED_ROTATE_F, LOG_EVENT_THREAD_SPECIFIC_F - for notes. + LOG_EVENT_TIME_F, LOG_EVENT_FORCED_ROTATE_F, + LOG_EVENT_THREAD_SPECIFIC_F, and LOG_EVENT_SUPPRESS_USE_F for + notes. */ uint16 flags; @@ -465,7 +479,7 @@ public: #ifndef MYSQL_CLIENT Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, - bool using_trans); + bool using_trans, bool suppress_use); const char* get_db() { return db; } #ifdef HAVE_REPLICATION void pack_info(Protocol* protocol); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d6f52fed1d2..60827d6d83e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1230,7 +1230,7 @@ bool change_password(THD *thd, const char *host, const char *user, new_password)); thd->clear_error(); mysql_update_log.write(thd, buff, query_length); - Query_log_event qinfo(thd, buff, query_length, 0); + Query_log_event qinfo(thd, buff, query_length, 0, FALSE); mysql_bin_log.write(&qinfo); DBUG_RETURN(0); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a5db02478ac..64e616e872f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -524,7 +524,7 @@ void close_temporary_tables(THD *thd) { /* The -1 is to remove last ',' */ thd->clear_error(); - Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0); + Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0, FALSE); /* Imagine the thread had created a temp table, then was doing a SELECT, and the SELECT was killed. Then it's not clever to mark the statement above as @@ -1441,7 +1441,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, { end = strxmov(strmov(query, "DELETE FROM `"), db,"`.`",name,"`", NullS); - Query_log_event qinfo(thd, query, (ulong)(end-query), 0); + Query_log_event qinfo(thd, query, (ulong)(end-query), 0, FALSE); mysql_bin_log.write(&qinfo); my_free(query, MYF(0)); } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 350a7432990..e3ca0328382 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -467,7 +467,29 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, mysql_update_log.write(thd, query, query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, query, query_length, 0); + Query_log_event qinfo(thd, query, query_length, 0, + /* suppress_use */ TRUE); + + /* + Write should use the database being created as the "current + database" and not the threads current database, which is the + default. If we do not change the "current database" to the + database being created, the CREATE statement will not be + replicated when using --binlog-do-db to select databases to be + replicated. + + An example (--binlog-do-db=sisyfos): + + CREATE DATABASE bob; # Not replicated + USE bob; # 'bob' is the current database + CREATE DATABASE sisyfos; # Not replicated since 'bob' is + # current database. + USE sisyfos; # Will give error on slave since + # database does not exist. + */ + qinfo.db = db; + qinfo.db_len = strlen(db); + mysql_bin_log.write(&qinfo); } send_ok(thd, result); @@ -517,7 +539,15 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) mysql_update_log.write(thd,thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, + /* suppress_use */ TRUE); + + // Write should use the database being created as the "current + // database" and not the threads current database, which is the + // default. + qinfo.db = db; + qinfo.db_len = strlen(db); + thd->clear_error(); mysql_bin_log.write(&qinfo); } @@ -625,7 +655,15 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) mysql_update_log.write(thd, query, query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, query, query_length, 0); + Query_log_event qinfo(thd, query, query_length, 0, + /* suppress_use */ TRUE); + + // Write should use the database being created as the "current + // database" and not the threads current database, which is the + // default. + qinfo.db = db; + qinfo.db_len = strlen(db); + thd->clear_error(); mysql_bin_log.write(&qinfo); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 09893970803..29d86a99ff3 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -216,7 +216,7 @@ cleanup: if (error <= 0) thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - log_delayed); + log_delayed, FALSE); if (mysql_bin_log.write(&qinfo) && transactional_table) error=1; } @@ -565,7 +565,7 @@ bool multi_delete::send_eof() if (error <= 0) thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - log_delayed); + log_delayed, FALSE); if (mysql_bin_log.write(&qinfo) && !normal_tables) local_error=1; // Log write failed: roll back the SQL statement } @@ -674,7 +674,7 @@ end: { thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - thd->tmp_table); + thd->tmp_table, FALSE); mysql_bin_log.write(&qinfo); } send_ok(thd); // This should return record count diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index d590d3b5093..3a2721e658d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -368,7 +368,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, if (error <= 0) thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - log_delayed); + log_delayed, FALSE); if (mysql_bin_log.write(&qinfo) && transactional_table) error=1; } @@ -1364,7 +1364,7 @@ bool delayed_insert::handle_inserts(void) mysql_update_log.write(&thd,row->query, row->query_length); if (row->log_query & DELAYED_LOG_BIN && using_bin_log) { - Query_log_event qinfo(&thd, row->query, row->query_length,0); + Query_log_event qinfo(&thd, row->query, row->query_length,0, FALSE); mysql_bin_log.write(&qinfo); } } @@ -1539,7 +1539,7 @@ void select_insert::send_error(uint errcode,const char *err) if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, - table->file->has_transactions()); + table->file->has_transactions(), FALSE); mysql_bin_log.write(&qinfo); } if (!table->tmp_table) @@ -1581,7 +1581,7 @@ bool select_insert::send_eof() if (!error) thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - table->file->has_transactions()); + table->file->has_transactions(), FALSE); mysql_bin_log.write(&qinfo); } if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e066e447345..f3d8307c4e0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2614,7 +2614,7 @@ unsent_create_error: if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } } @@ -2643,7 +2643,7 @@ unsent_create_error: if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } } @@ -2666,7 +2666,7 @@ unsent_create_error: if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } } @@ -3262,7 +3262,7 @@ purposes internal to the MySQL server", MYF(0)); mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } send_ok(thd); @@ -3278,7 +3278,7 @@ purposes internal to the MySQL server", MYF(0)); mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } send_ok(thd); @@ -3345,7 +3345,7 @@ purposes internal to the MySQL server", MYF(0)); if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } } @@ -3366,7 +3366,7 @@ purposes internal to the MySQL server", MYF(0)); if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } if (mqh_used && lex->sql_command == SQLCOM_GRANT) @@ -3409,7 +3409,7 @@ purposes internal to the MySQL server", MYF(0)); mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } } diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index afaf2ed0923..388034e0f1a 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -84,7 +84,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } send_ok(thd); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3a242dc6547..4529c7e83e1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -282,7 +282,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (!error) thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - tmp_table_deleted && !some_tables_deleted); + tmp_table_deleted && !some_tables_deleted, + FALSE); mysql_bin_log.write(&qinfo); } } @@ -1292,7 +1293,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, test(create_info->options & - HA_LEX_CREATE_TMP_TABLE)); + HA_LEX_CREATE_TMP_TABLE), + FALSE); mysql_bin_log.write(&qinfo); } } @@ -2217,7 +2219,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, test(create_info->options & - HA_LEX_CREATE_TMP_TABLE)); + HA_LEX_CREATE_TMP_TABLE), + FALSE); mysql_bin_log.write(&qinfo); } res= 0; @@ -2328,7 +2331,7 @@ mysql_discard_or_import_tablespace(THD *thd, mysql_update_log.write(thd, thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } err: @@ -2715,7 +2718,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } if (do_send_ok) @@ -3110,7 +3113,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } goto end_temporary; @@ -3245,7 +3248,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } VOID(pthread_cond_broadcast(&COND_refresh)); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d3597f274dc..21fcac34070 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -344,7 +344,7 @@ int mysql_update(THD *thd, if (error <= 0) thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - log_delayed); + log_delayed, FALSE); if (mysql_bin_log.write(&qinfo) && transactional_table) error=1; // Rollback update } @@ -1221,7 +1221,7 @@ bool multi_update::send_eof() if (local_error <= 0) thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - log_delayed); + log_delayed, FALSE); if (mysql_bin_log.write(&qinfo) && trans_safe) local_error= 1; // Rollback update } -- cgit v1.2.1 From dea513dd12e4f394c1c801006d3350c619f0b64f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Dec 2004 15:02:29 +0100 Subject: sql/sql_class.h Bug #6284 - report truncation warnings in INSERT ... SELECT only for "INSERT" part sql/sql_insert.cc Bug #6284 - report truncation warnings in INSERT ... SELECT only for "INSERT" part sql/sql_class.h: Bug #6284 - report truncation warnings in INSERT ... SELECT only for "INSERT" part sql/sql_insert.cc: Bug #6284 - report truncation warnings in INSERT ... SELECT only for "INSERT" part --- sql/sql_class.h | 3 ++- sql/sql_insert.cc | 43 +++++++++++++++++-------------------------- 2 files changed, 19 insertions(+), 27 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index d0d9afc7746..33cd248994a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1235,6 +1235,7 @@ class select_insert :public select_result_interceptor { ~select_insert(); int prepare(List &list, SELECT_LEX_UNIT *u); bool send_data(List &items); + virtual void store_values(List &values); void send_error(uint errcode,const char *err); bool send_eof(); /* not implemented: select_insert is never re-used in prepared statements */ @@ -1262,7 +1263,7 @@ public: create_info(create_info_par), lock(0) {} int prepare(List &list, SELECT_LEX_UNIT *u); - bool send_data(List &values); + void store_values(List &values); bool send_eof(); void abort(); }; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index d590d3b5093..fc4a5f8f9b8 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1457,7 +1457,6 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) restore_record(table,default_values); // Get empty record table->next_number_field=table->found_next_number_field; - thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields thd->cuted_fields=0; if (info.handle_duplicates == DUP_IGNORE || info.handle_duplicates == DUP_REPLACE) @@ -1487,27 +1486,34 @@ select_insert::~select_insert() bool select_insert::send_data(List &values) { DBUG_ENTER("select_insert::send_data"); + bool error=0; if (unit->offset_limit_cnt) { // using limit offset,count unit->offset_limit_cnt--; DBUG_RETURN(0); } - if (fields->elements) - fill_record(*fields, values, 1); - else - fill_record(table->field, values, 1); - if (thd->net.report_error || write_record(table,&info)) - DBUG_RETURN(1); - if (table->next_number_field) // Clear for next record + thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields + store_values(values); + error=thd->net.report_error || write_record(table,&info); + thd->count_cuted_fields= CHECK_FIELD_IGNORE; + if (!error && table->next_number_field) // Clear for next record { table->next_number_field->reset(); if (! last_insert_id && thd->insert_id_used) last_insert_id=thd->insert_id(); } - DBUG_RETURN(0); + DBUG_RETURN(error); } +void select_insert::store_values(List &values) +{ + if (fields->elements) + fill_record(*fields, values, 1); + else + fill_record(table->field, values, 1); +} + void select_insert::send_error(uint errcode,const char *err) { DBUG_ENTER("select_insert::send_error"); @@ -1637,7 +1643,6 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) table->next_number_field=table->found_next_number_field; restore_record(table,default_values); // Get empty record - thd->count_cuted_fields= CHECK_FIELD_WARN; // count warnings thd->cuted_fields=0; if (info.handle_duplicates == DUP_IGNORE || info.handle_duplicates == DUP_REPLACE) @@ -1647,23 +1652,9 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) } -bool select_create::send_data(List &values) +void select_create::store_values(List &values) { - if (unit->offset_limit_cnt) - { // using limit offset,count - unit->offset_limit_cnt--; - return 0; - } fill_record(field, values, 1); - if (thd->net.report_error ||write_record(table,&info)) - return 1; - if (table->next_number_field) // Clear for next record - { - table->next_number_field->reset(); - if (! last_insert_id && thd->insert_id_used) - last_insert_id=thd->insert_id(); - } - return 0; } @@ -1711,7 +1702,7 @@ void select_create::abort() enum db_type table_type=table->db_type; if (!table->tmp_table) { - ulong version= table->version; + ulong version= table->version; hash_delete(&open_cache,(byte*) table); if (!create_info->table_existed) quick_rm_table(table_type, db, name); -- cgit v1.2.1 From f2d6046eda1d0e210eb6aa68d6d604d2ef824918 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Dec 2004 15:18:25 +0100 Subject: Due to a compiler bug, slave.cc:tables_ok() sometimes wrongly returns 1 if the return type is int or int_fast8_t. The test case that showed this problem is rpl000001 and the tested version was MySQL 5.0.2. The compiler with the problem is GCC 3.0.4 runing on "Linux bitch 2.4.18 #2 Thu Apr 11 14:37:17 EDT 2002 sparc64 unknown". By changing the return type to bool the problem disappear. (Another way to make the problem disappear is to simply print the returned value with printf("%d",?). The printed returned value is always 0 in the test cases I have run.) This is only a partial solution to the problem, since someone could later change the return type of the function back to int or some other type that does not work. sql/slave.cc: Changed type sql/slave.h: Changed type --- sql/slave.cc | 2 +- sql/slave.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/slave.cc b/sql/slave.cc index b5caf2627a6..bd9650ed369 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -759,7 +759,7 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len) 1 should be logged/replicated */ -int tables_ok(THD* thd, TABLE_LIST* tables) +bool tables_ok(THD* thd, TABLE_LIST* tables) { bool some_tables_updating= 0; DBUG_ENTER("tables_ok"); diff --git a/sql/slave.h b/sql/slave.h index a4d123329c6..08cf0806717 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -496,7 +496,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi); int show_binlog_info(THD* thd); /* See if the query uses any tables that should not be replicated */ -int tables_ok(THD* thd, TABLE_LIST* tables); +bool tables_ok(THD* thd, TABLE_LIST* tables); /* Check to see if the database is ok to operate on with respect to the -- cgit v1.2.1 From a1fba2daccee3c7c5d46cded39fda7ee7f0d6eae Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Dec 2004 17:15:54 +0200 Subject: After merge fixes Fixed compiler warnings Fix core dump when sending SIGHUP to mysqld mysql-test/r/drop_temp_table.result: After merge fixes mysql-test/r/grant.result: After merge fixes mysql-test/r/group_min_max.result: After merge fixes mysql-test/r/innodb.result: After merge fixes mysql-test/r/insert_select.result: After merge fixes mysql-test/r/rpl_charset.result: After merge fixes mysql-test/r/rpl_create_database.result: After merge fixes mysql-test/r/rpl_loaddata_rule_m.result: After merge fixes mysql-test/t/rpl_charset.test: After merge fixes mysql-test/t/rpl_create_database.test: After merge fixes sql-common/client.c: After merge fixes sql/item.cc: After merge fixes sql/mysqld.cc: Fix core dump when sending SIGHUP to mysqld sql/sql_acl.cc: Better comment sql/sql_derived.cc: Fixed comment Added missing DBUG_RETURN sql/sql_insert.cc: Fixed compiler warnings After merge fixes sql/sql_lex.cc: After merge fixes Removed compiler warnings sql/sql_parse.cc: After merge fixes sql/sql_select.cc: More debugging sql/sql_table.cc: Added missing DBUG_VOID_RETURN sql/sql_update.cc: Fixed compiler warning sql/sql_view.cc: Added missing DBUG_RETURN Fixed compiler warnings Added flag to signal that the view is a derived table --- sql/item.cc | 2 ++ sql/mysqld.cc | 2 +- sql/sql_acl.cc | 3 ++- sql/sql_derived.cc | 6 +++--- sql/sql_insert.cc | 27 ++++++++++++++++----------- sql/sql_lex.cc | 3 ++- sql/sql_parse.cc | 12 ++++++------ sql/sql_select.cc | 50 ++++++++++++++++++++++++++++++++------------------ sql/sql_table.cc | 1 + sql/sql_update.cc | 6 ++---- sql/sql_view.cc | 5 +++-- 11 files changed, 70 insertions(+), 47 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 001fbef9505..03bbbe2ad49 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -187,6 +187,7 @@ Item_ident::Item_ident(THD *thd, Item_ident *item) void Item_ident::cleanup() { DBUG_ENTER("Item_ident::cleanup"); +#ifdef CANT_BE_USED_AS_MEMORY_IS_FREED DBUG_PRINT("enter", ("b:%s(%s), t:%s(%s), f:%s(%s)", db_name ? db_name : "(null)", orig_db_name ? orig_db_name : "(null)", @@ -194,6 +195,7 @@ void Item_ident::cleanup() orig_table_name ? orig_table_name : "(null)", field_name ? field_name : "(null)", orig_field_name ? orig_field_name : "(null)")); +#endif Item::cleanup(); db_name= orig_db_name; table_name= orig_table_name; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5e0cc47ecc5..42ae6982eb0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2128,7 +2128,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) { reload_acl_and_cache((THD*) 0, (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST | - REFRESH_STATUS | REFRESH_GRANT | + REFRESH_GRANT | REFRESH_THREADS | REFRESH_HOSTS), (TABLE_LIST*) 0, NULL); // Flush logs mysql_print_status((THD*) 0); // Send debug some info diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index b69ee068407..4d4923d16b8 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -446,7 +446,8 @@ void acl_free(bool end) SYNOPSIS acl_reload() - thd Thread handle + thd Thread handle. Note that this may be NULL if we refresh + because we got a signal */ void acl_reload(THD *thd) diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 10ef6a081b6..69511018880 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -77,7 +77,7 @@ mysql_handle_derived(LEX *lex, int (*processor)(THD*, LEX*, TABLE_LIST*)) Create temporary table structure (but do not fill it) SYNOPSIS - mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) + mysql_derived_prepare() thd Thread handle lex LEX for this thread orig_table_list TABLE_LIST for the upper SELECT @@ -103,6 +103,7 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list) { SELECT_LEX_UNIT *unit= orig_table_list->derived; int res= 0; + DBUG_ENTER("mysql_derived_prepare"); if (unit) { SELECT_LEX *first_select= unit->first_select(); @@ -110,7 +111,6 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list) select_union *derived_result; bool is_union= first_select->next_select() && first_select->next_select()->linkage == UNION_TYPE; - DBUG_ENTER("mysql_derived"); if (!(derived_result= new select_union(0))) DBUG_RETURN(1); // out of memory @@ -173,7 +173,7 @@ exit: } else if (orig_table_list->ancestor) orig_table_list->set_ancestor(); - return (res); + DBUG_RETURN(res); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 77a669e4c96..0814c7a747e 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -116,7 +116,8 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, Item *item; TABLE_LIST *tbl= 0; table_map map= 0; - while (item= it++) + + while ((item= it++)) map|= item->used_tables(); if (table_list->check_single_table(&tbl, map) || tbl == 0) { @@ -1840,19 +1841,23 @@ bool select_insert::send_data(List &values) DBUG_RETURN(0); } - thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields + thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields store_values(values); thd->count_cuted_fields= CHECK_FIELD_IGNORE; if (thd->net.report_error) DBUG_RETURN(1); - switch (table_list->view_check_option(thd, - thd->lex->duplicates == DUP_IGNORE)) { - case VIEW_CHECK_SKIP: - DBUG_RETURN(0); - case VIEW_CHECK_ERROR: - DBUG_RETURN(1); + if (table_list) // Not CREATE ... SELECT + { + switch (table_list->view_check_option(thd, + thd->lex->duplicates == + DUP_IGNORE)) { + case VIEW_CHECK_SKIP: + DBUG_RETURN(0); + case VIEW_CHECK_ERROR: + DBUG_RETURN(1); + } } - if (!(error= write_record(table,&info)) && table->next_number_field) + if (!(error= write_record(thd, table,&info)) && table->next_number_field) { /* Clear for next record */ table->next_number_field->reset(); @@ -1866,9 +1871,9 @@ bool select_insert::send_data(List &values) void select_insert::store_values(List &values) { if (fields->elements) - fill_record(*fields, values, 1); + fill_record(thd, *fields, values, 1); else - fill_record(table->field, values, 1); + fill_record(thd, table->field, values, 1); } void select_insert::send_error(uint errcode,const char *err) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 8a705a7438b..12e4d912f15 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -144,8 +144,9 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->select_lex.init_order(); lex->select_lex.group_list.empty(); lex->describe= 0; - lex->subqueries= lex->derived_tables= FALSE; + lex->subqueries= FALSE; lex->view_prepare_mode= FALSE; + lex->derived_tables= 0; lex->lock_option= TL_READ; lex->found_colon= 0; lex->safe_to_cache_query= 1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 44adc28d41d..168632f7578 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -615,7 +615,7 @@ end: } -static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0) +static void reset_mqh(LEX_USER *lu, bool get_them= 0) { #ifndef NO_EMBEDDED_ACCESS_CHECKS (void) pthread_mutex_lock(&LOCK_user_conn); @@ -3396,7 +3396,7 @@ create_error: { if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); mysql_bin_log.write(&qinfo); } send_ok(thd); @@ -3512,7 +3512,7 @@ create_error: List_iterator str_list(lex->users_list); LEX_USER *user; while ((user=str_list++)) - reset_mqh(thd,user); + reset_mqh(user); } } } @@ -5637,7 +5637,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, acl_reload(thd); grant_reload(thd); if (mqh_used) - reset_mqh(thd,(LEX_USER *) NULL,TRUE); + reset_mqh((LEX_USER *) NULL,TRUE); } #endif if (options & REFRESH_LOG) @@ -5713,7 +5713,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, } if (options & REFRESH_HOSTS) hostname_cache_refresh(); - if (options & REFRESH_STATUS) + if (thd && (options & REFRESH_STATUS)) refresh_status(); if (options & REFRESH_THREADS) flush_thread_cache(); @@ -5743,7 +5743,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, } #endif if (options & REFRESH_USER_RESOURCES) - reset_mqh(thd,(LEX_USER *) NULL); + reset_mqh((LEX_USER *) NULL); if (write_to_binlog) *write_to_binlog= tmp_write_to_binlog; return result; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ba9933a3d15..1049c074ce1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1249,7 +1249,7 @@ JOIN::exec() /* Copy data to the temporary table */ thd->proc_info= "Copying to tmp table"; - + DBUG_PRINT("info", ("%s", thd->proc_info)); if ((tmp_error= do_select(curr_join, (List *) 0, curr_tmp_table, 0))) { error= tmp_error; @@ -1377,6 +1377,7 @@ JOIN::exec() } thd->proc_info="Copying to group table"; + DBUG_PRINT("info", ("%s", thd->proc_info)); tmp_error= -1; if (curr_join != this) { @@ -1615,6 +1616,7 @@ JOIN::exec() else { thd->proc_info="Sending data"; + DBUG_PRINT("info", ("%s", thd->proc_info)); error= do_select(curr_join, curr_fields_list, NULL, procedure); thd->limit_found_rows= curr_join->send_records; thd->examined_row_count= curr_join->examined_rows; @@ -1910,6 +1912,8 @@ void Cursor::close() { THD *thd= join->thd; + DBUG_ENTER("Cursor::close"); + join->join_free(0); if (unit) { @@ -1940,6 +1944,7 @@ Cursor::close() } join= 0; unit= 0; + DBUG_VOID_RETURN; } @@ -4718,11 +4723,12 @@ get_best_combination(JOIN *join) KEYUSE *keyuse; uint table_count; THD *thd=join->thd; + DBUG_ENTER("get_best_combination"); table_count=join->tables; if (!(join->join_tab=join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count))) - return TRUE; + DBUG_RETURN(TRUE); join->full_join=0; @@ -4736,6 +4742,7 @@ get_best_combination(JOIN *join) form->reginfo.join_tab=j; if (!*j->on_expr_ref) form->reginfo.not_exists_optimize=0; // Only with LEFT JOIN + DBUG_PRINT("info",("type: %d", j->type)); if (j->type == JT_CONST) continue; // Handled in make_join_stat.. @@ -4751,13 +4758,13 @@ get_best_combination(JOIN *join) join->full_join=1; } else if (create_ref_for_key(join, j, keyuse, used_tables)) - return TRUE; // Something went wrong + DBUG_RETURN(TRUE); // Something went wrong } for (i=0 ; i < table_count ; i++) join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i; update_depend_map(join); - return 0; + DBUG_RETURN(0); } @@ -4770,6 +4777,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, uint keyparts,length,key; TABLE *table; KEY *keyinfo; + DBUG_ENTER("create_ref_for_key"); /* Use best key from find_best */ table=j->table; @@ -4819,7 +4827,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, (keyparts+1)))) || !(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts))) { - return TRUE; + DBUG_RETURN(TRUE); } j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length); j->ref.key_err=1; @@ -4832,7 +4840,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, { j->ref.items[0]=((Item_func*)(keyuse->val))->key_item(); if (keyuse->used_tables) - return TRUE; // not supported yet. SerG + DBUG_RETURN(TRUE); // not supported yet. SerG j->type=JT_FT; } @@ -4856,7 +4864,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, maybe_null ? (char*) key_buff : 0, keyinfo->key_part[i].length, keyuse->val); if (thd->is_fatal_error) - return TRUE; + DBUG_RETURN(TRUE); tmp.copy(); } else @@ -4876,7 +4884,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, } /* not ftkey */ *ref_key=0; // end_marker if (j->type == JT_FT) - return 0; + DBUG_RETURN(0); if (j->type == JT_CONST) j->table->const_table= 1; else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY | @@ -4900,7 +4908,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, } else j->type=JT_EQ_REF; - return 0; + DBUG_RETURN(0); } @@ -4963,10 +4971,11 @@ make_simple_join(JOIN *join,TABLE *tmp_table) { TABLE **tableptr; JOIN_TAB *join_tab; + DBUG_ENTER("make_simple_join"); if (!(tableptr=(TABLE**) join->thd->alloc(sizeof(TABLE*))) || !(join_tab=(JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB)))) - return TRUE; + DBUG_RETURN(TRUE); join->join_tab=join_tab; join->table=tableptr; tableptr[0]=tmp_table; join->tables=1; @@ -4996,10 +5005,11 @@ make_simple_join(JOIN *join,TABLE *tmp_table) join_tab->not_used_in_distinct=0; join_tab->read_first_record= join_init_read_record; join_tab->join=join; + join_tab->ref.key_parts= 0; bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record)); tmp_table->status=0; tmp_table->null_row=0; - return FALSE; + DBUG_RETURN(FALSE); } @@ -8122,6 +8132,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, keyinfo->key_length=0; keyinfo->rec_per_key=0; keyinfo->algorithm= HA_KEY_ALG_UNDEF; + keyinfo->name= (char*) "group_key"; for (; group ; group=group->next,key_part_info++) { Field *field=(*group->item)->get_tmp_table_field(); @@ -8192,7 +8203,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, keyinfo->key_part=key_part_info; keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL; keyinfo->key_length=(uint16) reclength; - keyinfo->name=(char*) "tmp"; + keyinfo->name= (char*) "distinct_key"; keyinfo->algorithm= HA_KEY_ALG_UNDEF; if (null_pack_length) { @@ -11973,6 +11984,8 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, { List_iterator_fast it(all_fields); Item *item_field,*item; + DBUG_ENTER("change_to_use_tmp_fields"); + res_selected_fields.empty(); res_all_fields.empty(); @@ -11996,8 +12009,8 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, else item_field= (Item*) new Item_field(field); if (!item_field) - return TRUE; // Fatal error - item_field->name= item->name; /*lint -e613 */ + DBUG_RETURN(TRUE); // Fatal error + item_field->name= item->name; #ifndef DBUG_OFF if (_db_on_ && !item_field->name) { @@ -12021,7 +12034,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, for (i= 0; i < border; i++) itr++; itr.sublist(res_selected_fields, elements); - return FALSE; + DBUG_RETURN(FALSE); } @@ -12092,10 +12105,11 @@ change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array, static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr) { Item_sum *func; + DBUG_ENTER("setup_sum_funcs"); while ((func= *(func_ptr++))) if (func->setup(thd)) - return TRUE; - return FALSE; + DBUG_RETURN(TRUE); + DBUG_RETURN(FALSE); } @@ -12617,10 +12631,10 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(new Item_string(join_type_str[tab->type], strlen(join_type_str[tab->type]), cs)); - uint j; /* Build "possible_keys" value and add it to item_list */ if (!tab->keys.is_clear_all()) { + uint j; for (j=0 ; j < table->keys ; j++) { if (tab->keys.is_set(j)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a1e09d74620..c0ddfdb2f07 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1670,6 +1670,7 @@ void close_cached_table(THD *thd, TABLE *table) /* When lock on LOCK_open is freed other threads can continue */ pthread_cond_broadcast(&COND_refresh); + DBUG_VOID_RETURN; } static int send_check_errmsg(THD *thd, TABLE_LIST* table, diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 7c55f281f38..9613e39d403 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -776,12 +776,10 @@ bool mysql_multi_update_prepare(THD *thd) */ List_iterator_fast it(*fields); Item *item; - while (item= it++) - { + while ((item= it++)) item->cleanup(); - } - /* We have to cleunup translation tables of views. */ + /* We have to cleanup translation tables of views. */ for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global) tbl->cleanup_items(); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index ec63bb92c54..993a4d1987b 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -312,7 +312,7 @@ bool mysql_create_view(THD *thd, send_ok(thd); lex->link_first_table_back(view, link_to_local); - return 0; + DBUG_RETURN(0); err: thd->proc_info= "end"; @@ -793,7 +793,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) /* re-nest tables of VIEW */ { List_iterator_fast ti(nested_join->join_list); - while(tbl= ti++) + while ((tbl= ti++)) { tbl->join_list= &nested_join->join_list; tbl->embedding= table; @@ -832,6 +832,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) view_select->linkage= DERIVED_TABLE_TYPE; table->updatable= 0; table->effective_with_check= VIEW_CHECK_NONE; + old_lex->subqueries= TRUE; /* SELECT tree link */ lex->unit.include_down(table->select_lex); -- cgit v1.2.1