From 6d271a529676021f3e1a1d60c3bf88818f678568 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Mon, 1 Sep 2003 15:36:53 +0500 Subject: [PATCH 01/89] Fix for Bug #1142 './configure - error in file causes failure of compile (SSL option needed)' --- acinclude.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index f6bd1d9e83e..146f1d18afb 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -745,7 +745,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \ /usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do - if test -f $d/libssl.a ; then + if test -f $d/libssl.a || test -f $d/libssl.dylib ; then OPENSSL_LIB=$d fi done @@ -757,7 +757,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ if test -f $incs/openssl/ssl.h ; then OPENSSL_INCLUDE=-I$incs fi - if test -f $libs/libssl.a ; then + if test -f $libs/libssl.a || test -f $d/libssl.dylib ; then OPENSSL_LIB=$libs fi ;; From e78f51fbe9dcb9f85bde79c44ad5e069356c0d73 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Tue, 11 Nov 2003 18:14:49 +0400 Subject: [PATCH 02/89] Fix for bug #1564: CREATE TABLE + UNION + same table name = crash --- mysql-test/r/union.result | 3 +++ mysql-test/t/union.test | 3 +++ sql/sql_parse.cc | 10 ++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 9899b8279e2..cd5d600edf4 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -419,4 +419,7 @@ a 3 (SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1; Wrong usage/placement of 'SQL_CALC_FOUND_ROWS' +create temporary table t1 select a from t1 union select a from t2; +create table t1 select a from t1 union select a from t2; +INSERT TABLE 't1' isn't allowed in FROM table list drop table t1,t2; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index ea7bdb4ee1b..ba4673e9a88 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -223,4 +223,7 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1; --error 1234 (SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1; +create temporary table t1 select a from t1 union select a from t2; +--error 1093 +create table t1 select a from t1 union select a from t2; drop table t1,t2; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0789a1768d1..a9183c84128 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3496,6 +3496,9 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) return 0; } + /* We should skip first table if SQL command is SQLCOM_CREATE_TABLE */ + bool skip_first= (lex->sql_command == SQLCOM_CREATE_TABLE); + bool first_added= 0; SELECT_LEX *sl; TABLE_LIST **new_table_list= result, *aux; @@ -3512,9 +3515,11 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) TABLE_LIST *next; for (; aux; aux=next) { - TABLE_LIST *cursor; + TABLE_LIST *cursor= *result; + if (first_added && skip_first) + cursor= cursor->next; next= aux->next; - for (cursor= *result; cursor; cursor=cursor->next) + for ( ; cursor; cursor=cursor->next) if (!strcmp(cursor->db,aux->db) && !strcmp(cursor->real_name,aux->real_name) && !strcmp(cursor->alias, aux->alias)) @@ -3531,6 +3536,7 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) *new_table_list= cursor; new_table_list= &cursor->next; *new_table_list=0; // end result list + first_added= 1; } else aux->shared=1; // Mark that it's used twice From f159963c0020d537fe450d0c9874101ea166dff0 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Mon, 17 Nov 2003 18:34:06 +0400 Subject: [PATCH 03/89] Fix for bug #1564: 'CREATE TABLE + UNION + same table name = crash' (related to previous changeset) --- sql/sql_parse.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a9183c84128..54cb3ade404 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -62,7 +62,8 @@ static void remove_escape(char *name); static void refresh_status(void); static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name); -static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result); +static bool create_total_list(THD *thd, LEX *lex, + TABLE_LIST **result, bool skip_first); const char *any_db="*any*"; // Special symbol for check_access @@ -1352,7 +1353,9 @@ mysql_execute_command(void) #endif } - if (lex->select_lex.next && create_total_list(thd,lex,&tables)) + if (lex->select_lex.next && + create_total_list(thd,lex,&tables, + (lex->sql_command == SQLCOM_CREATE_TABLE))) DBUG_VOID_RETURN; /* @@ -3487,7 +3490,8 @@ void set_lock_for_tables(thr_lock_type lock_type) ** to the entries in this list. */ -static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) +static bool create_total_list(THD *thd, LEX *lex, + TABLE_LIST **result, bool skip_first) { /* Handle the case when we are not using union */ if (!lex->select_lex.next) @@ -3497,8 +3501,6 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) } /* We should skip first table if SQL command is SQLCOM_CREATE_TABLE */ - bool skip_first= (lex->sql_command == SQLCOM_CREATE_TABLE); - bool first_added= 0; SELECT_LEX *sl; TABLE_LIST **new_table_list= result, *aux; @@ -3516,7 +3518,7 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) for (; aux; aux=next) { TABLE_LIST *cursor= *result; - if (first_added && skip_first) + if (skip_first && cursor) cursor= cursor->next; next= aux->next; for ( ; cursor; cursor=cursor->next) @@ -3536,7 +3538,6 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) *new_table_list= cursor; new_table_list= &cursor->next; *new_table_list=0; // end result list - first_added= 1; } else aux->shared=1; // Mark that it's used twice From f6ca9afdbdbb4219b29a05bfc9c1e380414f251b Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 18 Nov 2003 15:58:27 +0200 Subject: [PATCH 04/89] Fix for bug when zeros are to be prepended to decimal field --- mysql-test/r/type_decimal.result | 6 ++++++ mysql-test/t/type_decimal.test | 6 ++++++ sql/field.cc | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index b74765696a2..df5402c89a8 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -363,3 +363,9 @@ CREATE TABLE t1 (a_dec DECIMAL(-2,1)); Too big column length for column 'a_dec' (max = 255). Use BLOB instead CREATE TABLE t1 (a_dec DECIMAL(-1,1)); Too big column length for column 'a_dec' (max = 255). Use BLOB instead +create table t1(a decimal(10,4)); +insert into t1 values ("+0000100000000"); +select * from t1; +a +9999999.9999 +drop table t1; diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 7aedc051905..14d9625710b 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -240,3 +240,9 @@ CREATE TABLE t1 (a_dec DECIMAL(-1,0)); CREATE TABLE t1 (a_dec DECIMAL(-2,1)); --error 1074 CREATE TABLE t1 (a_dec DECIMAL(-1,1)); + +# Zero prepend overflow bug +create table t1(a decimal(10,4)); +insert into t1 values ("+0000100000000"); +select * from t1; +drop table t1; diff --git a/sql/field.cc b/sql/field.cc index 43481ca0963..58781624239 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -632,7 +632,7 @@ void Field_decimal::store(const char *from,uint len) if (zerofill) { left_wall=to-1; - while (pos != left_wall) // Fill with zeros + while (pos > left_wall) // Fill with zeros *pos--='0'; } else @@ -640,7 +640,7 @@ void Field_decimal::store(const char *from,uint len) left_wall=to+(sign_char != 0)-1; if (!expo_sign_char) // If exponent was specified, ignore prezeros { - for (;pos != left_wall && pre_zeros_from !=pre_zeros_end; + for (;pos > left_wall && pre_zeros_from !=pre_zeros_end; pre_zeros_from++) *pos--= '0'; } From a1ceb1bd049a14a72f1ccf1cc8556e6930c07af5 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Thu, 20 Nov 2003 18:12:49 +0200 Subject: [PATCH 05/89] database invalidation invalidate queries only of given database (BUG#1898) --- mysql-test/r/query_cache.result | 11 +++++++++-- mysql-test/t/query_cache.test | 4 ++++ sql/sql_cache.cc | 34 +++++++++++++++++++++++++++------ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 83d2e439fbc..c7554211a1a 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -365,16 +365,23 @@ insert into mysqltest.t1 (a) values (1); select * from mysqltest.t1 where i is null; i a 1 1 +create table t1(a int); +select * from t1; +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 select * from mysqltest.t1; i a 1 1 show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 1 +Qcache_queries_in_cache 2 drop database mysqltest; show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 0 +Qcache_queries_in_cache 1 +drop table t1; create table t1 (a char(1) not null); insert into t1 values("á"); select * from t1; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 2ab5504f84b..ad0dc80e2f7 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -251,10 +251,14 @@ select * from mysqltest.t1 where i is null; # # drop db # +create table t1(a int); +select * from t1; +show status like "Qcache_queries_in_cache"; select * from mysqltest.t1; show status like "Qcache_queries_in_cache"; drop database mysqltest; show status like "Qcache_queries_in_cache"; +drop table t1; # # Charset convertion (cp1251_koi8 always present) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 5d525c7be4e..8610fcb8f22 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1151,9 +1151,29 @@ void Query_cache::invalidate(char *db) if (query_cache_size > 0) { DUMP(this); - /* invalidate_table reduce list while only root of list remain */ - while (tables_blocks !=0 ) - invalidate_table(tables_blocks); + restart_search: + if (tables_blocks) + { + Query_cache_block *curr= tables_blocks; + Query_cache_block *next; + do + { + next= curr->next; + if (strcmp(db, (char*)(curr->table()->db())) == 0) + invalidate_table(curr); + /* + invalidate_table can freed block on which point 'next' (if + table of this block used only in queries which was deleted + by invalidate_table). As far as we do not allocate new blocks + and mark all headers of freed blocks as 'FREE' (even if they are + merged with other blocks) we can just test type of block + to be sure that block is not deleted + */ + if (next->type == Query_cache_block::FREE) + goto restart_search; + curr= next; + } while (curr != tables_blocks); + } } STRUCT_UNLOCK(&structure_guard_mutex); } @@ -2158,9 +2178,11 @@ void Query_cache::free_memory_block(Query_cache_block *block) { DBUG_ENTER("Query_cache::free_memory_block"); block->used=0; - DBUG_PRINT("qcache",("first_block 0x%lx, block 0x%lx, pnext 0x%lx pprev 0x%lx", - (ulong) first_block, (ulong) block,block->pnext, - (ulong) block->pprev)); + block->type= Query_cache_block::FREE; // mark block as free in any case + DBUG_PRINT("qcache", + ("first_block 0x%lx, block 0x%lx, pnext 0x%lx pprev 0x%lx", + (ulong) first_block, (ulong) block,block->pnext, + (ulong) block->pprev)); if (block->pnext != first_block && block->pnext->is_free()) block = join_free_blocks(block, block->pnext); From c4a9dc4f8ba59dac3f8b5dfdf983cbef19bc34df Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Fri, 21 Nov 2003 00:03:04 +0300 Subject: [PATCH 06/89] fix for bug #1790: "BIT_AND() result in GROUP BY different when SQL_BIG_RESULT used" return value of BIT_AND changed to BIGINT SIGNED Also the patch fixes another bug: when temporary table is in use and one of values in group is NULL, BIT_AND always returns zero. Fixed it to always skip null values. --- mysql-test/r/func_group.result | 14 ++++++------- sql/item_sum.cc | 36 ++++++++++++---------------------- sql/item_sum.h | 22 ++++++++++++++++----- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 80ccb6c7bb8..a1563271917 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -47,7 +47,7 @@ sum(all a) count(all a) avg(all a) std(all a) bit_or(all a) bit_and(all a) min(a 21 6 3.5000 1.7078 7 0 1 6 E select grp, sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp; grp sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c) -NULL NULL 0 NULL NULL 0 0 NULL NULL +NULL NULL 0 NULL NULL 0 -1 NULL NULL 1 1 1 1.0000 0.0000 1 1 1 1 a a 2 5 2 2.5000 0.5000 3 2 2 3 b c 3 15 3 5.0000 0.8165 7 4 4 6 C E @@ -218,8 +218,8 @@ insert into t1 values (1,null); insert into t1 values (2,null); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL 0 0 -2 0 NULL NULL NULL NULL NULL 0 0 +1 0 NULL NULL NULL NULL NULL -1 0 +2 0 NULL NULL NULL NULL NULL -1 0 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) 1 0 NULL NULL NULL NULL NULL -1 0 @@ -227,8 +227,8 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) insert into t1 values (2,1); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL 0 0 -2 1 1 1.0000 0.0000 1 1 0 1 +1 0 NULL NULL NULL NULL NULL -1 0 +2 1 1 1.0000 0.0000 1 1 1 1 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) 1 0 NULL NULL NULL NULL NULL -1 0 @@ -236,8 +236,8 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) insert into t1 values (3,1); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL 0 0 -2 1 1 1.0000 0.0000 1 1 0 1 +1 0 NULL NULL NULL NULL NULL -1 0 +2 1 1 1.0000 0.0000 1 1 1 1 3 1 1 1.0000 0.0000 1 1 1 1 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 835278ae262..36a3c6b009b 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -614,10 +614,19 @@ void Item_sum_avg::reset_field() } void Item_sum_bit::reset_field() +{ + char *res= result_field->ptr; + bits= reset_bits; + add(); + int8store(res, bits); +} + +void Item_sum_bit::update_field() { char *res=result_field->ptr; - ulonglong nr=(ulonglong) args[0]->val_int(); - int8store(res,nr); + bits= uint8korr(res); + add(); + int8store(res, bits); } /* @@ -756,28 +765,6 @@ Item_sum_hybrid::min_max_update_int_field() } -void Item_sum_or::update_field() -{ - ulonglong nr; - char *res=result_field->ptr; - - nr=uint8korr(res); - nr|= (ulonglong) args[0]->val_int(); - int8store(res,nr); -} - - -void Item_sum_and::update_field() -{ - ulonglong nr; - char *res=result_field->ptr; - - nr=uint8korr(res); - nr&= (ulonglong) args[0]->val_int(); - int8store(res,nr); -} - - Item_avg_field::Item_avg_field(Item_sum_avg *item) { name=item->name; @@ -787,6 +774,7 @@ Item_avg_field::Item_avg_field(Item_sum_avg *item) maybe_null=1; } + double Item_avg_field::val() { double nr; diff --git a/sql/item_sum.h b/sql/item_sum.h index 5189566fdfb..c91abbded28 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -55,7 +55,18 @@ public: virtual enum Sumfunctype sum_func () const=0; virtual void reset()=0; virtual bool add()=0; + /* + Called when new group is started and results are being saved in + a temporary table. Similar to reset(), but must also store value in + result_field. Like reset() it is supposed to reset start value to + default. + */ virtual void reset_field()=0; + /* + Called for each new value in the group, when temporary table is in use. + Similar to add(), but uses temporary table field to obtain current value, + Updated value is then saved in the field. + */ virtual void update_field()=0; virtual bool keep_field_type(void) const { return 0; } virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } @@ -360,20 +371,20 @@ class Item_sum_bit :public Item_sum_int void reset(); longlong val_int(); void reset_field(); + void update_field(); unsigned int size_of() { return sizeof(*this);} - void fix_length_and_dec() - { decimals=0; max_length=21; unsigned_flag=1; maybe_null=null_value=0; } }; class Item_sum_or :public Item_sum_bit { - public: +public: Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} bool add(); - void update_field(); const char *func_name() const { return "bit_or"; } unsigned int size_of() { return sizeof(*this);} + void fix_length_and_dec() + { decimals=0; max_length=21; unsigned_flag=1; maybe_null=null_value=0; } }; @@ -382,9 +393,10 @@ class Item_sum_and :public Item_sum_bit public: Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {} bool add(); - void update_field(); const char *func_name() const { return "bit_and"; } unsigned int size_of() { return sizeof(*this);} + void fix_length_and_dec() + { decimals=0; max_length=21; unsigned_flag=0; maybe_null=null_value=0; } }; /* From 3ff69d5dc4ae7c2161b1956bd3f006443e9b3d2b Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Mon, 24 Nov 2003 13:57:49 +0400 Subject: [PATCH 07/89] Fix for bug #1855: mysqld crashes with certain SSL connections --- sql/sql_acl.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 065394c87d0..03a359d44e7 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -588,6 +588,11 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, /* Prepare certificate (if exists) */ DBUG_PRINT("info",("checkpoint 1")); X509* cert=SSL_get_peer_certificate(ssl); + if (!cert) + { + user_access=NO_ACCESS; + break; + } DBUG_PRINT("info",("checkpoint 2")); /* If X509 issuer is speified, we check it... */ if (acl_user->x509_issuer) From 612109ffa0ea9cb52f13268d124682f135683edb Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Mon, 1 Dec 2003 14:59:35 +0100 Subject: [PATCH 08/89] Removing unneeded code: the Intvar_log_event constructor calls the Log_event constructor which does e.server_id=thd.server_id. --- sql/log.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 33ca82aa14f..e6eaa3b802c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1110,8 +1110,6 @@ bool MYSQL_LOG::write(Log_event* event_info) Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT, thd->current_insert_id); e.set_log_pos(this); - if (thd->server_id) - e.server_id = thd->server_id; if (e.write(file)) goto err; } @@ -1119,8 +1117,6 @@ bool MYSQL_LOG::write(Log_event* event_info) { Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id); e.set_log_pos(this); - if (thd->server_id) - e.server_id = thd->server_id; if (e.write(file)) goto err; } From 7eda171f9a9f17183335d53094a6e5f6ce5450cd Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Tue, 2 Dec 2003 16:49:46 +0100 Subject: [PATCH 09/89] There is no reason that Intvar_log_event's constructor calls Log_event::Log_event() instead of Log_event::Log_event(THD*, ...) when the event is built in the master to be written in the binlog. Rand_log_event already used the good constructor, so there really is no reason for Intvar_log_event to be an exception. This fixes a test failure of last night (which appeared after I removed a useless e.server_id=thd->server_id in log.cc; in fact this line was not useless because it hid the bad constructor). Replication tests pass, with Valgrind too. --- sql/log_event.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/log_event.h b/sql/log_event.h index 2e6b7373dc2..929d550951e 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -529,7 +529,7 @@ public: #ifndef MYSQL_CLIENT Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg) - :Log_event(),val(val_arg),type(type_arg) + :Log_event(thd_arg,0,0),val(val_arg),type(type_arg) {} void pack_info(String* packet); int exec_event(struct st_relay_log_info* rli); From cf192063d14e9121e6f74ee11957f3fb9f989020 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Tue, 2 Dec 2003 19:39:51 +0300 Subject: [PATCH 10/89] Post-review fixes for bug #1790 'BIT_AND() result in GROUP BY different when SQL_BIG_RESULT used': - BIT_AND now returns BIGINT UNSIGNED - in case there were no matching rows BIT_AND returns 18446744073709551615 (but not NULL), BIT_OR returns 0 (but not NULL). That's how Monty wants it and how is described in our docs. --- include/my_global.h | 14 ++++++++++++++ mysql-test/r/func_group.result | 10 +++++----- sql/item_sum.cc | 6 ++---- sql/item_sum.h | 14 ++++++-------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 349ac8ac82e..68c331aa414 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -603,11 +603,25 @@ extern double my_atof(const char*); #define HAVE_LONG_LONG 1 #endif +/* + Some pre-ANSI-C99 systems like AIX 5.1 and Linux/GCC 2.95 define + ULONGLONG_MAX, LONGLONG_MIN, LONGLONG_MAX; we use them if they're defined. +*/ + #if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN) #define LONGLONG_MIN ((long long) 0x8000000000000000LL) #define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL) #endif +#if defined(HAVE_LONG_LONG) && !defined(ULONLONG_MAX) +/* First check for ANSI C99 definition: */ +#ifdef ULLONG_MAX +#define ULONGLONG_MAX ULLONG_MAX +#else +#define ULONGLONG_MAX ((unsigned long long)(~0ULL)) +#endif +#endif /* defined (HAVE_LONG_LONG) && !defined(ULONLONG_MAX)*/ + #if SIZEOF_LONG == 4 #define INT_MIN32 (long) 0x80000000L #define INT_MAX32 (long) 0x7FFFFFFFL diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index a1563271917..f6a30813bb0 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -47,7 +47,7 @@ sum(all a) count(all a) avg(all a) std(all a) bit_or(all a) bit_and(all a) min(a 21 6 3.5000 1.7078 7 0 1 6 E select grp, sum(a),count(a),avg(a),std(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp; grp sum(a) count(a) avg(a) std(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c) -NULL NULL 0 NULL NULL 0 -1 NULL NULL +NULL NULL 0 NULL NULL 0 18446744073709551615 NULL NULL 1 1 1 1.0000 0.0000 1 1 1 1 a a 2 5 2 2.5000 0.5000 3 2 2 3 b c 3 15 3 5.0000 0.8165 7 4 4 6 C E @@ -218,8 +218,8 @@ insert into t1 values (1,null); insert into t1 values (2,null); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL -1 0 -2 0 NULL NULL NULL NULL NULL -1 0 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 +2 0 NULL NULL NULL NULL NULL 18446744073709551615 0 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) 1 0 NULL NULL NULL NULL NULL -1 0 @@ -227,7 +227,7 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) insert into t1 values (2,1); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL -1 0 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 2 1 1 1.0000 0.0000 1 1 1 1 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) @@ -236,7 +236,7 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) insert into t1 values (3,1); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL -1 0 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 2 1 1 1.0000 0.0000 1 1 1 1 3 1 1 1.0000 0.0000 1 1 1 1 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 36a3c6b009b..5a5934db0cd 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -615,10 +615,8 @@ void Item_sum_avg::reset_field() void Item_sum_bit::reset_field() { - char *res= result_field->ptr; - bits= reset_bits; - add(); - int8store(res, bits); + reset(); + int8store(result_field->ptr, bits); } void Item_sum_bit::update_field() diff --git a/sql/item_sum.h b/sql/item_sum.h index c91abbded28..d3a328be032 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -361,10 +361,10 @@ public: class Item_sum_bit :public Item_sum_int { - protected: +protected: ulonglong reset_bits,bits; - public: +public: Item_sum_bit(Item *item_par,ulonglong reset_arg) :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {} enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;} @@ -373,6 +373,8 @@ class Item_sum_bit :public Item_sum_int void reset_field(); void update_field(); unsigned int size_of() { return sizeof(*this);} + void fix_length_and_dec() + { decimals=0; max_length=21; unsigned_flag=1; maybe_null=null_value=0; } }; @@ -383,20 +385,16 @@ public: bool add(); const char *func_name() const { return "bit_or"; } unsigned int size_of() { return sizeof(*this);} - void fix_length_and_dec() - { decimals=0; max_length=21; unsigned_flag=1; maybe_null=null_value=0; } }; class Item_sum_and :public Item_sum_bit { - public: - Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {} +public: + Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {} bool add(); const char *func_name() const { return "bit_and"; } unsigned int size_of() { return sizeof(*this);} - void fix_length_and_dec() - { decimals=0; max_length=21; unsigned_flag=0; maybe_null=null_value=0; } }; /* From dd37ef055b73645e3f6314239ab276106c3bfa1f Mon Sep 17 00:00:00 2001 From: "dlenev@mysql.com" <> Date: Tue, 2 Dec 2003 20:25:45 +0300 Subject: [PATCH 11/89] Fix for Bug #1448 "Date parsing fails, and fails to complain about it". Now numbers representing illegal timestamps are converted to 0 value if they are stored as timestamp or datetime. This behaviour is consistent with manual and with behaviour of string -> timestamp conversion. --- mysql-test/r/type_datetime.result | 15 ++++++- mysql-test/r/type_timestamp.result | 20 ++++++++- mysql-test/t/type_datetime.test | 5 ++- mysql-test/t/type_timestamp.test | 7 ++- sql/field.cc | 70 +++++++++++++++++++++--------- 5 files changed, 89 insertions(+), 28 deletions(-) diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 5df4f355cfb..756deab80e0 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -1,6 +1,6 @@ drop table if exists t1; create table t1 (t datetime); -insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959); +insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959),(20030102030460),(20030102036301),(20030102240401),(20030132030401),(20031302030460); select * from t1; t 2000-01-01 00:00:00 @@ -15,6 +15,11 @@ t 1999-12-31 23:59:59 1000-01-01 00:00:00 9999-12-31 23:59:59 +0000-00-00 00:00:00 +0000-00-00 00:00:00 +0000-00-00 00:00:00 +0000-00-00 00:00:00 +0000-00-00 00:00:00 delete from t1 where t > 0; optimize table t1; Table Op Msg_type Msg_text @@ -22,7 +27,8 @@ test.t1 optimize status OK check table t1; Table Op Msg_type Msg_text test.t1 check status OK -insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"); +delete from t1; +insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030102030460"),("20030102036301"),("20030102240401"),("20030132030401"),("20031302030460"); select * from t1; t 2000-01-01 00:00:00 @@ -38,6 +44,11 @@ t 1999-12-31 23:59:59 1000-01-01 00:00:00 9999-12-31 23:59:59 +0000-00-00 00:00:00 +0000-00-00 00:00:00 +0000-00-00 00:00:00 +0000-00-00 00:00:00 +0000-00-00 00:00:00 drop table t1; CREATE TABLE t1 (a timestamp, b date, c time, d datetime); insert into t1 (b,c,d) values(now(),curtime(),now()); diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 3d5d74709c1..9403b73d459 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -43,7 +43,7 @@ date_format(a,"%Y %y") year(a) year(now()) 1970 70 1970 1970 drop table t1; create table t1 (ix timestamp); -insert into t1 values (19991101000000),(19990102030405),(19990630232922),(19990601000000),(19990930232922),(19990531232922),(19990501000000),(19991101000000),(19990501000000); +insert into t1 values (19991101000000),(19990102030405),(19990630232922),(19990601000000),(19990930232922),(19990531232922),(19990501000000),(19991101000000),(19990501000000),(20030101010160),(20030101016001),(20030101240101),(20030132010101),(20031301010101); select * from t1; ix 19991101000000 @@ -55,6 +55,24 @@ ix 19990501000000 19991101000000 19990501000000 +00000000000000 +00000000000000 +00000000000000 +00000000000000 +00000000000000 +delete from t1; +insert into t1 values ("19991101000000"),("19990102030405"),("19990630232922"),("19990601000000"),("20030101010160"),("20030101016001"),("20030101240101"),("20030132010101"),("20031301010101"); +select * from t1; +ix +19991101000000 +19990102030405 +19990630232922 +19990601000000 +00000000000000 +00000000000000 +00000000000000 +00000000000000 +00000000000000 drop table t1; CREATE TABLE t1 (date date, date_time datetime, time_stamp timestamp); INSERT INTO t1 VALUES ("1998-12-31","1998-12-31 23:59:59",19981231235959); diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 51b65d00243..850e5238111 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -4,12 +4,13 @@ drop table if exists t1; create table t1 (t datetime); -insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959); +insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959),(20030102030460),(20030102036301),(20030102240401),(20030132030401),(20031302030460); select * from t1; delete from t1 where t > 0; optimize table t1; check table t1; -insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"); +delete from t1; +insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030102030460"),("20030102036301"),("20030102240401"),("20030132030401"),("20031302030460"); select * from t1; drop table t1; diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index eb0def74a17..0c88f1b8025 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -34,8 +34,11 @@ select date_format(a,"%Y %y"),year(a),year(now()) from t1; drop table t1; create table t1 (ix timestamp); -insert into t1 values (19991101000000),(19990102030405),(19990630232922),(19990601000000),(19990930232922),(19990531232922),(19990501000000),(19991101000000),(19990501000000); -select * from t1; +insert into t1 values (19991101000000),(19990102030405),(19990630232922),(19990601000000),(19990930232922),(19990531232922),(19990501000000),(19991101000000),(19990501000000),(20030101010160),(20030101016001),(20030101240101),(20030132010101),(20031301010101); +select * from t1; +delete from t1; +insert into t1 values ("19991101000000"),("19990102030405"),("19990630232922"),("19990601000000"),("20030101010160"),("20030101016001"),("20030101240101"),("20030132010101"),("20031301010101"); +select * from t1; drop table t1; CREATE TABLE t1 (date date, date_time datetime, time_stamp timestamp); diff --git a/sql/field.cc b/sql/field.cc index 43481ca0963..259314cb4db 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2520,31 +2520,59 @@ void Field_timestamp::store(double nr) ** function. */ -static longlong fix_datetime(longlong nr) +static longlong fix_datetime(longlong nr, TIME *time_res) { + long part1,part2; + if (nr == LL(0) || nr >= LL(10000101000000)) - return nr; // Normal datetime >= Year 1000 + goto ok; if (nr < 101) goto err; if (nr <= (YY_PART_YEAR-1)*10000L+1231L) - return (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069 + { + nr= (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069 + goto ok; + } if (nr < (YY_PART_YEAR)*10000L+101L) goto err; if (nr <= 991231L) - return (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999 + { + nr= (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999 + goto ok; + } if (nr < 10000101L) goto err; if (nr <= 99991231L) - return nr*1000000L; + { + nr= nr*1000000L; + goto ok; + } if (nr < 101000000L) goto err; if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959)) - return nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069 + { + nr= nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069 + goto ok; + } if (nr < YY_PART_YEAR*LL(10000000000)+ LL(101000000)) goto err; if (nr <= LL(991231235959)) - return nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999 + nr= nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999 + ok: + part1=(long) (nr/LL(1000000)); + part2=(long) (nr - (longlong) part1*LL(1000000)); + time_res->year= (int) (part1/10000L); part1%=10000L; + time_res->month= (int) part1 / 100; + time_res->day= (int) part1 % 100; + time_res->hour= (int) (part2/10000L); part2%=10000L; + time_res->minute=(int) part2 / 100; + time_res->second=(int) part2 % 100; + + if (time_res->month <= 12 && time_res->day <= 31 && time_res->hour <= 23 && + time_res->minute <= 59 && time_res->second <= 59) + return nr; + err: current_thd->cuted_fields++; return LL(0); @@ -2555,20 +2583,18 @@ void Field_timestamp::store(longlong nr) { TIME l_time; time_t timestamp; - long part1,part2; - if ((nr=fix_datetime(nr))) + if ((nr=fix_datetime(nr, &l_time))) { long not_used; - part1=(long) (nr/LL(1000000)); - part2=(long) (nr - (longlong) part1*LL(1000000)); - l_time.year= (int) (part1/10000L); part1%=10000L; - l_time.month= (int) part1 / 100; - l_time.day= (int) part1 % 100; - l_time.hour= (int) (part2/10000L); part2%=10000L; - l_time.minute=(int) part2 / 100; - l_time.second=(int) part2 % 100; - timestamp=my_gmt_sec(&l_time, ¬_used); + + if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR) + { + current_thd->cuted_fields++; + timestamp=0; + } + else + timestamp=my_gmt_sec(&l_time, ¬_used); } else timestamp=0; @@ -3406,13 +3432,15 @@ void Field_datetime::store(double nr) void Field_datetime::store(longlong nr) { - if (nr < 0 || nr > LL(99991231235959)) + TIME l_time; + + nr=fix_datetime(nr, &l_time); + + if (l_time.year > 9999) { nr=0; current_thd->cuted_fields++; } - else - nr=fix_datetime(nr); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { From 486415233e8350e6540972f2c1678a5f77d6d7ce Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Tue, 2 Dec 2003 21:05:40 +0300 Subject: [PATCH 12/89] Fix for bug #1980 --- BitKeeper/etc/logging_ok | 1 + mysql-test/r/multi_update.result | 26 ++++++++++++++++++ mysql-test/t/multi_update.test | 46 ++++++++++++++++++++++++++++++++ sql/uniques.cc | 14 +++++++--- 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 9dea6a7fa44..17af13c2e75 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -103,6 +103,7 @@ serg@serg.mylan serg@serg.mysql.com serg@sergbook.mylan serg@sergbook.mysql.com +sergefp@mysql.com sinisa@rhols221.adsl.netsonic.fi tfr@beta.frontier86.ee tfr@indrek.tfr.cafe.ee diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 350cea420b6..233c99fb22b 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -327,3 +327,29 @@ select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and a b a b 2 2 NULL NULL drop table t1,t2; +set @ttype_save=@@table_type; +set @@table_type=innodb; +create table t1 ( c char(8) not null ); +insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); +insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); +alter table t1 add b char(8) not null; +alter table t1 add a char(8) not null; +alter table t1 add primary key (a,b,c); +update t1 set a=c, b=c; +create table t2 like t1; +insert into t2 select * from t1; +delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; +drop table t1,t2; +set @@table_type=bdb; +create table t1 ( c char(8) not null ); +insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); +insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); +alter table t1 add b char(8) not null; +alter table t1 add a char(8) not null; +alter table t1 add primary key (a,b,c); +update t1 set a=c, b=c; +create table t2 like t1; +insert into t2 select * from t1; +delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; +set @@table_type=@ttype_save; +drop table t1,t2; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 7aa4e74cec0..bf6c3db9306 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -267,3 +267,49 @@ insert into t2 values (1,1), (3,1); update t1 left join t2 on t1.a=t2.a set t1.b=2, t2.b=2 where t1.b=1 and t2.b=1 or t2.a is NULL; select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and t2.b=1 or t2.a is NULL; drop table t1,t2; + +# +# Test for bug #1980. +# +set @ttype_save=@@table_type; + +--disable_warnings +set @@table_type=innodb; +create table t1 ( c char(8) not null ); +--enable_warnings + +insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); +insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); + +alter table t1 add b char(8) not null; +alter table t1 add a char(8) not null; +alter table t1 add primary key (a,b,c); +update t1 set a=c, b=c; + +create table t2 like t1; +insert into t2 select * from t1; + +delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; + +drop table t1,t2; + +--disable_warnings +set @@table_type=bdb; +create table t1 ( c char(8) not null ); +--enable_warnings + +insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); +insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); + +alter table t1 add b char(8) not null; +alter table t1 add a char(8) not null; +alter table t1 add primary key (a,b,c); +update t1 set a=c, b=c; + +create table t2 like t1; +insert into t2 select * from t1; + +delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; + +set @@table_type=@ttype_save; +drop table t1,t2; diff --git a/sql/uniques.cc b/sql/uniques.cc index d00893a8605..967392d12d5 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -37,14 +37,20 @@ int unique_write_to_file(gptr key, element_count count, Unique *unique) { + /* + Use unique->size (size of element stored in the tree) and not + unique->tree.size_of_element. The latter is different from unique->size + when tree implementation chooses to store pointer to key in TREE_ELEMENT + (instead of storing the element itself there) + */ return my_b_write(&unique->file, (byte*) key, - unique->tree.size_of_element) ? 1 : 0; + unique->size) ? 1 : 0; } int unique_write_to_ptrs(gptr key, element_count count, Unique *unique) { - memcpy(unique->record_pointers, key, unique->tree.size_of_element); - unique->record_pointers+=unique->tree.size_of_element; + memcpy(unique->record_pointers, key, unique->size); + unique->record_pointers+=unique->size; return 0; } @@ -132,7 +138,7 @@ bool Unique::get(TABLE *table) bzero((char*) &sort_param,sizeof(sort_param)); sort_param.max_rows= elements; sort_param.sort_form=table; - sort_param.sort_length=sort_param.ref_length=tree.size_of_element; + sort_param.sort_length=sort_param.ref_length=size; sort_param.keys= max_in_memory_size / sort_param.sort_length; sort_param.not_killable=1; From 53aa633b240a68dc619c9f9184025aefd8819b71 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 3 Dec 2003 13:56:33 +0100 Subject: [PATCH 13/89] - Bugfix for the Mac OS X startup script: Suppress the annoying "$1: unbound variable" error when no option was given --- support-files/MacOSX/MySQL | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/support-files/MacOSX/MySQL b/support-files/MacOSX/MySQL index dfba5f8f982..f6579700384 100755 --- a/support-files/MacOSX/MySQL +++ b/support-files/MacOSX/MySQL @@ -11,6 +11,13 @@ # Written by Lenz Grimmer # +# Suppress the annoying "$1: unbound variable" error when no option +# was given +if [ -z $1 ] ; then + echo "Usage: $0 [start|stop|restart] " + exit 1 +fi + # Source the common setup functions for startup scripts test -r /etc/rc.common || exit 1 . /etc/rc.common From 70ff7b8254260ebeaa068c355c8b65266ff0834c Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Wed, 3 Dec 2003 19:49:31 +0300 Subject: [PATCH 14/89] Fix for bug #1980 tests --- mysql-test/r/multi_update.result | 4 ++-- mysql-test/t/multi_update.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 233c99fb22b..d286b01c1c7 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -336,7 +336,7 @@ alter table t1 add b char(8) not null; alter table t1 add a char(8) not null; alter table t1 add primary key (a,b,c); update t1 set a=c, b=c; -create table t2 like t1; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)); insert into t2 select * from t1; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; drop table t1,t2; @@ -348,7 +348,7 @@ alter table t1 add b char(8) not null; alter table t1 add a char(8) not null; alter table t1 add primary key (a,b,c); update t1 set a=c, b=c; -create table t2 like t1; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)); insert into t2 select * from t1; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; set @@table_type=@ttype_save; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index bf6c3db9306..fb2a1ff2b6f 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -286,7 +286,7 @@ alter table t1 add a char(8) not null; alter table t1 add primary key (a,b,c); update t1 set a=c, b=c; -create table t2 like t1; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)); insert into t2 select * from t1; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; @@ -306,7 +306,7 @@ alter table t1 add a char(8) not null; alter table t1 add primary key (a,b,c); update t1 set a=c, b=c; -create table t2 like t1; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)); insert into t2 select * from t1; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; From d626c313e5c5fb46f0629996bf3f94ee2adeae68 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Thu, 4 Dec 2003 14:12:01 +0400 Subject: [PATCH 15/89] Fix for bug#1944 'Function RPad() sometimes produce unexpected result' --- mysql-test/r/func_str.result | 18 ++++++++++++------ mysql-test/t/func_str.test | 6 ++++-- sql/item_strfunc.cc | 4 ++-- sql/item_strfunc.h | 4 ++-- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 0bac5111a05..dcb788f520f 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -119,12 +119,12 @@ montymontymontymontymonty * * select reverse('abc'),reverse('abcd'); reverse('abc') reverse('abcd') cba dcba -select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12'); -rpad('a',4,'1') rpad('a',4,'12') rpad('abcd',3,'12') -a111 a121 abc -select lpad('a',4,'1'),lpad('a',4,'12'),lpad('abcd',3,'12'); -lpad('a',4,'1') lpad('a',4,'12') lpad('abcd',3,'12') -111a 121a abc +select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12'), rpad(11, 10 , 22), rpad("ab", 10, 22); +rpad('a',4,'1') rpad('a',4,'12') rpad('abcd',3,'12') rpad(11, 10 , 22) rpad("ab", 10, 22) +a111 a121 abc 1122222222 ab22222222 +select lpad('a',4,'1'),lpad('a',4,'12'),lpad('abcd',3,'12'), lpad(11, 10 , 22); +lpad('a',4,'1') lpad('a',4,'12') lpad('abcd',3,'12') lpad(11, 10 , 22) +111a 121a abc 2222222211 select rpad(741653838,17,'0'),lpad(741653838,17,'0'); rpad(741653838,17,'0') lpad(741653838,17,'0') 74165383800000000 00000000741653838 @@ -134,6 +134,12 @@ abcdaba abaabcd select rpad('abcd',1,'ab'),lpad('abcd',1,'ab'); rpad('abcd',1,'ab') lpad('abcd',1,'ab') a a +select rpad('STRING', 20, CONCAT('p','a','d') ); +rpad('STRING', 20, CONCAT('p','a','d') ) +STRINGpadpadpadpadpa +select lpad('STRING', 20, CONCAT('p','a','d') ); +lpad('STRING', 20, CONCAT('p','a','d') ) +padpadpadpadpaSTRING select LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD'),GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD'); LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD') GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD') HAROLD HARRY diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 5ea3654134b..b07b0b635c1 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -49,11 +49,13 @@ select aes_decrypt("a","a"); select aes_decrypt(aes_encrypt("","a"),"a"); select repeat('monty',5),concat('*',space(5),'*'); select reverse('abc'),reverse('abcd'); -select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12'); -select lpad('a',4,'1'),lpad('a',4,'12'),lpad('abcd',3,'12'); +select rpad('a',4,'1'),rpad('a',4,'12'),rpad('abcd',3,'12'), rpad(11, 10 , 22), rpad("ab", 10, 22); +select lpad('a',4,'1'),lpad('a',4,'12'),lpad('abcd',3,'12'), lpad(11, 10 , 22); select rpad(741653838,17,'0'),lpad(741653838,17,'0'); select rpad('abcd',7,'ab'),lpad('abcd',7,'ab'); select rpad('abcd',1,'ab'),lpad('abcd',1,'ab'); +select rpad('STRING', 20, CONCAT('p','a','d') ); +select lpad('STRING', 20, CONCAT('p','a','d') ); select LEAST(NULL,'HARRY','HARRIOT',NULL,'HAROLD'),GREATEST(NULL,'HARRY','HARRIOT',NULL,'HAROLD'); select least(1,2,3) | greatest(16,32,8), least(5,4)*1,greatest(-1.0,1.0)*1,least(3,2,1)*1.0,greatest(1,1.1,1.0),least("10",9),greatest("A","B","0"); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index fe9c8b9e099..dd1ec6bd2da 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1806,7 +1806,7 @@ String *Item_func_rpad::val_str(String *str) const char *ptr_pad; int32 count= (int32) args[1]->val_int(); String *res =args[0]->val_str(str); - String *rpad = args[2]->val_str(str); + String *rpad = args[2]->val_str(&rpad_str); if (!res || args[1]->null_value || !rpad || count < 0) goto err; @@ -1866,7 +1866,7 @@ String *Item_func_lpad::val_str(String *str) const char *ptr_pad; ulong count= (long) args[1]->val_int(); String *res= args[0]->val_str(str); - String *lpad= args[2]->val_str(str); + String *lpad= args[2]->val_str(&lpad_str); if (!res || args[1]->null_value || !lpad) goto err; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 5c9706ed633..fc98ebfe67d 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -436,7 +436,7 @@ public: class Item_func_rpad :public Item_str_func { - String tmp_value; + String tmp_value, rpad_str; public: Item_func_rpad(Item *arg1,Item *arg2,Item *arg3) :Item_str_func(arg1,arg2,arg3) {} @@ -449,7 +449,7 @@ public: class Item_func_lpad :public Item_str_func { - String tmp_value; + String tmp_value, lpad_str; public: Item_func_lpad(Item *arg1,Item *arg2,Item *arg3) :Item_str_func(arg1,arg2,arg3) {} From 1b4bd22bd72e4e0ab31f5e85fd38506f7bcac3a9 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Thu, 4 Dec 2003 15:30:14 +0100 Subject: [PATCH 16/89] Fix for BUG#2011 "rare race condition producing "binlog has bad magic number" error in slave". The problem was that when the slave SQL thread reads a hot relay log (hot = the one being written to by the slave I/O thread), it must have the LOCK_log. It already took it for read_log_event(), but needs it also for check_binlog_magic(). This should fix all recently reported failures of the rpl_max_relay_size test in 4.1 and 5.0 (though the bug exists since 4.0, it showed up first in 5.0). --- sql/slave.cc | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 6816d968007..5bc31fd6a21 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3497,8 +3497,20 @@ rli->relay_log_pos=%s rli->pending=%lu", sizeof(rli->relay_log_name)-1); flush_relay_log_info(rli); } - - // next log is hot + + /* + Now we want to open this next log. To know if it's a hot log (the one + being written by the I/O thread now) or a cold log, we can use + is_active(); if it is hot, we use the I/O cache; if it's cold we open + the file normally. But if is_active() reports that the log is hot, this + may change between the test and the consequence of the test. So we may + open the I/O cache whereas the log is now cold, which is nonsense. + To guard against this, we need to have LOCK_log. + */ + + DBUG_PRINT("info",("hot_log: %d",hot_log)); + if (!hot_log) /* if hot_log, we already have this mutex */ + pthread_mutex_lock(log_lock); if (rli->relay_log.is_active(rli->linfo.log_file_name)) { #ifdef EXTRA_DEBUG @@ -3511,15 +3523,24 @@ rli->relay_log_pos=%s rli->pending=%lu", /* Read pointer has to be at the start since we are the only - reader + reader. + We must keep the LOCK_log to read the 4 first bytes, as this is a hot + log (same as when we call read_log_event() above: for a hot log we + take the mutex). */ if (check_binlog_magic(cur_log,&errmsg)) + { + if (!hot_log) pthread_mutex_unlock(log_lock); goto err; + } + if (!hot_log) pthread_mutex_unlock(log_lock); continue; } + if (!hot_log) pthread_mutex_unlock(log_lock); /* - if we get here, the log was not hot, so we will have to - open it ourselves + if we get here, the log was not hot, so we will have to open it + ourselves. We are sure that the log is still not hot now (a log can get + from hot to cold, but not from cold to hot). No need for LOCK_log. */ #ifdef EXTRA_DEBUG sql_print_error("next log '%s' is not active", From e4d2cbc0da92646de76a70f741cae90eeb62cb90 Mon Sep 17 00:00:00 2001 From: "dlenev@mysql.com" <> Date: Thu, 4 Dec 2003 19:02:48 +0300 Subject: [PATCH 17/89] Fix undeterministic behaviour of year check if we failed to classify integer as datetime in Field_datetime::store(). Stylistic clean-ups. --- sql/field.cc | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index 259314cb4db..1070d0f7b7d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2569,7 +2569,8 @@ static longlong fix_datetime(longlong nr, TIME *time_res) time_res->minute=(int) part2 / 100; time_res->second=(int) part2 % 100; - if (time_res->month <= 12 && time_res->day <= 31 && time_res->hour <= 23 && + if (time_res->year <= 9999 && time_res->month <= 12 && + time_res->day <= 31 && time_res->hour <= 23 && time_res->minute <= 59 && time_res->second <= 59) return nr; @@ -2584,7 +2585,7 @@ void Field_timestamp::store(longlong nr) TIME l_time; time_t timestamp; - if ((nr=fix_datetime(nr, &l_time))) + if ((nr= fix_datetime(nr, &l_time))) { long not_used; @@ -3432,15 +3433,10 @@ void Field_datetime::store(double nr) void Field_datetime::store(longlong nr) { - TIME l_time; + TIME not_used; - nr=fix_datetime(nr, &l_time); + nr= fix_datetime(nr, ¬_used); - if (l_time.year > 9999) - { - nr=0; - current_thd->cuted_fields++; - } #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) { From e36fd284471674673e8489ba188976032df72b84 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 4 Dec 2003 19:48:10 +0200 Subject: [PATCH 18/89] Allow space in service names move bdb/innodb tests to right places --- mysql-test/r/bdb.result | 11 ++++++++ mysql-test/r/innodb.result | 11 ++++++++ mysql-test/r/multi_update.result | 26 ------------------ mysql-test/t/bdb.test | 19 +++++++++++++ mysql-test/t/innodb.test | 19 +++++++++++++ mysql-test/t/multi_update.test | 46 -------------------------------- sql/mysqld.cc | 2 +- 7 files changed, 61 insertions(+), 73 deletions(-) diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index ebc2866183c..05845df9dd3 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -1154,3 +1154,14 @@ x 7 6 drop table t1; +create table t1 ( c char(8) not null ) type=bdb; +insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); +insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); +alter table t1 add b char(8) not null; +alter table t1 add a char(8) not null; +alter table t1 add primary key (a,b,c); +update t1 set a=c, b=c; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=bdb; +insert into t2 select * from t1; +delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; +drop table t1,t2; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index e9cdf962022..3938fc80f10 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1222,3 +1222,14 @@ a b 111 100 111 100 drop table t1; +create table t1 ( c char(8) not null ) type=innodb; +insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); +insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); +alter table t1 add b char(8) not null; +alter table t1 add a char(8) not null; +alter table t1 add primary key (a,b,c); +update t1 set a=c, b=c; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=innodb; +insert into t2 select * from t1; +delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; +drop table t1,t2; diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index d286b01c1c7..350cea420b6 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -327,29 +327,3 @@ select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and a b a b 2 2 NULL NULL drop table t1,t2; -set @ttype_save=@@table_type; -set @@table_type=innodb; -create table t1 ( c char(8) not null ); -insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); -insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); -alter table t1 add b char(8) not null; -alter table t1 add a char(8) not null; -alter table t1 add primary key (a,b,c); -update t1 set a=c, b=c; -create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)); -insert into t2 select * from t1; -delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; -drop table t1,t2; -set @@table_type=bdb; -create table t1 ( c char(8) not null ); -insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); -insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); -alter table t1 add b char(8) not null; -alter table t1 add a char(8) not null; -alter table t1 add primary key (a,b,c); -update t1 set a=c, b=c; -create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)); -insert into t2 select * from t1; -delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; -set @@table_type=@ttype_save; -drop table t1,t2; diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test index d0cc63a9389..2dfaecba9b1 100644 --- a/mysql-test/t/bdb.test +++ b/mysql-test/t/bdb.test @@ -796,3 +796,22 @@ select * from t1 where x <= 10 and x >= 7 order by x desc; select * from t1 where x <= 8 and x >= 5 order by x desc; select * from t1 where x < 8 and x > 5 order by x desc; drop table t1; + +# +# Test of multi-table-updates (bug #1980). +# + +create table t1 ( c char(8) not null ) type=bdb; +insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); +insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); + +alter table t1 add b char(8) not null; +alter table t1 add a char(8) not null; +alter table t1 add primary key (a,b,c); +update t1 set a=c, b=c; + +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=bdb; +insert into t2 select * from t1; + +delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; +drop table t1,t2; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index e46f5801418..ea9c5e0cf55 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -838,3 +838,22 @@ update t1 set b=100 where a=1 order by b desc limit 2; update t1 set a=a+10+b where a=1 order by b; select * from t1 order by a,b; drop table t1; + +# +# Test of multi-table-updates (bug #1980). +# + +create table t1 ( c char(8) not null ) type=innodb; +insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); +insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); + +alter table t1 add b char(8) not null; +alter table t1 add a char(8) not null; +alter table t1 add primary key (a,b,c); +update t1 set a=c, b=c; + +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=innodb; +insert into t2 select * from t1; + +delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; +drop table t1,t2; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index fb2a1ff2b6f..7aa4e74cec0 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -267,49 +267,3 @@ insert into t2 values (1,1), (3,1); update t1 left join t2 on t1.a=t2.a set t1.b=2, t2.b=2 where t1.b=1 and t2.b=1 or t2.a is NULL; select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and t2.b=1 or t2.a is NULL; drop table t1,t2; - -# -# Test for bug #1980. -# -set @ttype_save=@@table_type; - ---disable_warnings -set @@table_type=innodb; -create table t1 ( c char(8) not null ); ---enable_warnings - -insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); -insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); - -alter table t1 add b char(8) not null; -alter table t1 add a char(8) not null; -alter table t1 add primary key (a,b,c); -update t1 set a=c, b=c; - -create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)); -insert into t2 select * from t1; - -delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; - -drop table t1,t2; - ---disable_warnings -set @@table_type=bdb; -create table t1 ( c char(8) not null ); ---enable_warnings - -insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); -insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); - -alter table t1 add b char(8) not null; -alter table t1 add a char(8) not null; -alter table t1 add primary key (a,b,c); -update t1 set a=c, b=c; - -create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)); -insert into t2 select * from t1; - -delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; - -set @@table_type=@ttype_save; -drop table t1,t2; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4c6cf1d5039..2e87ade9174 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2573,7 +2573,7 @@ default_service_handling(char **argv, } /* We must have servicename last */ *pos++= ' '; - strmake(pos, servicename, (uint) (end+2 - pos)); + (void) add_quoted_string(pos, servicename, end); if (Service.got_service_option(argv, "install")) { From 5af1c00a1d45896529f64104be3b97aea8f45c1e Mon Sep 17 00:00:00 2001 From: "greg@mysql.com" <> Date: Thu, 4 Dec 2003 13:58:21 -0500 Subject: [PATCH 19/89] Fix InstallShield 'String Tables could not be loaded' issue --- .../4.0.XX-classic/String Tables/0009-English/value.shl | 2 +- .../4.0.XX-gpl/String Tables/0009-English/value.shl | 2 +- .../4.0.XX-pro/String Tables/0009-English/value.shl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VC++Files/InstallShield/4.0.XX-classic/String Tables/0009-English/value.shl b/VC++Files/InstallShield/4.0.XX-classic/String Tables/0009-English/value.shl index 5f767a63f43..868c801c68c 100755 --- a/VC++Files/InstallShield/4.0.XX-classic/String Tables/0009-English/value.shl +++ b/VC++Files/InstallShield/4.0.XX-classic/String Tables/0009-English/value.shl @@ -19,5 +19,5 @@ ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able t [General] Language=0009 Type=STRINGTABLESPECIFIC -Version=@VERSION@ +Version=1.00.000 diff --git a/VC++Files/InstallShield/4.0.XX-gpl/String Tables/0009-English/value.shl b/VC++Files/InstallShield/4.0.XX-gpl/String Tables/0009-English/value.shl index 0a6c33be42b..35e7c278cc9 100755 --- a/VC++Files/InstallShield/4.0.XX-gpl/String Tables/0009-English/value.shl +++ b/VC++Files/InstallShield/4.0.XX-gpl/String Tables/0009-English/value.shl @@ -19,5 +19,5 @@ ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able t [General] Language=0009 Type=STRINGTABLESPECIFIC -Version=@VERSION@ +Version=1.00.000 diff --git a/VC++Files/InstallShield/4.0.XX-pro/String Tables/0009-English/value.shl b/VC++Files/InstallShield/4.0.XX-pro/String Tables/0009-English/value.shl index 61b2e6fb50f..525f3be0b3e 100755 --- a/VC++Files/InstallShield/4.0.XX-pro/String Tables/0009-English/value.shl +++ b/VC++Files/InstallShield/4.0.XX-pro/String Tables/0009-English/value.shl @@ -19,5 +19,5 @@ ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able t [General] Language=0009 Type=STRINGTABLESPECIFIC -Version=@VERSION@ +Version=1.00.000 From dd2303ce072f185b02b50b58d841c70687f41bf9 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Thu, 4 Dec 2003 22:42:18 +0100 Subject: [PATCH 20/89] - Fix for BUG#1858 "SQL-Thread stops working when using optimize table": we change THD::system_thread from a 'bool' to a bitmap to be able to distinguish between delayed-insert threads and slave threads. - Fix for BUG#1701 "Update from multiple tables" (one line in sql_parse.cc, plus a new test rpl_multi_update.test). That's just adding an initialization. --- mysql-test/r/rpl_multi_update.result | 27 +++++++++++++++++++++++++++ mysql-test/t/rpl_multi_update.test | 25 +++++++++++++++++++++++++ sql/repl_failsafe.cc | 7 +++++++ sql/slave.cc | 4 +++- sql/sql_class.h | 9 +++++++-- sql/sql_insert.cc | 2 +- sql/sql_parse.cc | 6 ++++++ 7 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 mysql-test/r/rpl_multi_update.result create mode 100644 mysql-test/t/rpl_multi_update.test diff --git a/mysql-test/r/rpl_multi_update.result b/mysql-test/r/rpl_multi_update.result new file mode 100644 index 00000000000..1fa1dd104d2 --- /dev/null +++ b/mysql-test/r/rpl_multi_update.result @@ -0,0 +1,27 @@ +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 unsigned not null auto_increment primary key, +b int unsigned, +) TYPE=MyISAM; +CREATE TABLE t2 ( +a int unsigned not null auto_increment primary key, +b int unsigned +) TYPE=MyISAM; +INSERT INTO t1 VALUES (NULL, 0); +INSERT INTO t1 SELECT NULL, 0 FROM t1; +INSERT INTO t2 VALUES (NULL, 0), (NULL,1); +SELECT * FROM t1 ORDER BY a; +a b +1 0 +2 0 +SELECT * FROM t2 ORDER BY a; +a b +1 0 +2 1 +UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a; diff --git a/mysql-test/t/rpl_multi_update.test b/mysql-test/t/rpl_multi_update.test new file mode 100644 index 00000000000..c44239594dd --- /dev/null +++ b/mysql-test/t/rpl_multi_update.test @@ -0,0 +1,25 @@ +source include/master-slave.inc; +drop table if exists t1,t2; + +CREATE TABLE t1 ( + a int unsigned not null auto_increment primary key, + b int unsigned, +) TYPE=MyISAM; + +CREATE TABLE t2 ( + a int unsigned not null auto_increment primary key, + b int unsigned +) TYPE=MyISAM; + +INSERT INTO t1 VALUES (NULL, 0); +INSERT INTO t1 SELECT NULL, 0 FROM t1; + +INSERT INTO t2 VALUES (NULL, 0), (NULL,1); + +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a; +save_master_pos; +connection slave; +sync_with_master; diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 8deb23e8586..6b91d81b487 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -52,6 +52,13 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, const char* log_file_name, char* errmsg); +/* + All of the functions defined in this file which are not used (the ones to + handle failsafe) are not used; their code has not been updated for more than + one year now so should be considered as BADLY BROKEN. Do not enable it. + The used functions (to handle LOAD DATA FROM MASTER, plus some small + functions like register_slave()) are working. +*/ static int init_failsafe_rpl_thread(THD* thd) { diff --git a/sql/slave.cc b/sql/slave.cc index 5bc31fd6a21..25eeb34e3a7 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2021,7 +2021,9 @@ improper_arguments: %d timed_out: %d", static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) { DBUG_ENTER("init_slave_thread"); - thd->system_thread = thd->bootstrap = 1; + thd->system_thread = (thd_type == SLAVE_THD_SQL) ? + SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO; + thd->bootstrap= 1; thd->host_or_ip= ""; thd->client_capabilities = 0; my_net_init(&thd->net, 0); diff --git a/sql/sql_class.h b/sql/sql_class.h index 58543a3d230..9287a0c8c79 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -460,7 +460,7 @@ public: long dbug_thread_id; pthread_t real_id; uint current_tablenr,tmp_table,cond_count; - uint server_status,open_options; + uint server_status,open_options,system_thread; uint32 query_length; uint32 db_length; /* variables.transaction_isolation is reset to this after each commit */ @@ -470,7 +470,7 @@ public: bool set_query_id,locked,count_cuted_fields,some_tables_deleted; bool no_errors, allow_sum_func, password, fatal_error; bool query_start_used,last_insert_id_used,insert_id_used,rand_used; - bool system_thread,in_lock_tables,global_read_lock; + bool in_lock_tables,global_read_lock; bool query_error, bootstrap, cleanup_done; bool safe_to_cache_query; bool volatile killed; @@ -592,6 +592,11 @@ public: CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length); }; +/* Flags for the THD::system_thread (bitmap) variable */ +#define SYSTEM_THREAD_DELAYED_INSERT 1 +#define SYSTEM_THREAD_SLAVE_IO 2 +#define SYSTEM_THREAD_SLAVE_SQL 4 + /* Used to hold information about file and file structure in exchainge via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3aefee61c27..3414e76e092 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -550,7 +550,7 @@ public: thd.command=COM_DELAYED_INSERT; bzero((char*) &thd.net,sizeof(thd.net)); // Safety - thd.system_thread=1; + thd.system_thread= SYSTEM_THREAD_DELAYED_INSERT; thd.host_or_ip= ""; bzero((char*) &info,sizeof(info)); pthread_mutex_init(&mutex,MY_MUTEX_INIT_FAST); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0789a1768d1..2d40d6fcf36 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2902,6 +2902,12 @@ mysql_init_query(THD *thd) thd->lex.select_lex.table_list.first=0; thd->lex.select_lex.table_list.next= (byte**) &thd->lex.select_lex.table_list.first; thd->lex.select_lex.next=0; + /* + select_lex.options is also inited in dispatch_command(), but for + replication (which bypasses dispatch_command() and calls mysql_parse() + directly) we must do it here. + */ + thd->lex.select_lex.options=0; thd->lex.olap=0; thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE; thd->fatal_error=0; // Safety From b5bef2956410f98f3d3e2f8fe2d8c4828e0ef0ff Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Fri, 5 Dec 2003 12:52:07 +0300 Subject: [PATCH 21/89] attempt to make ULONGLONG_MAX work on Windows. --- include/config-win.h | 1 + include/my_global.h | 1 + 2 files changed, 2 insertions(+) diff --git a/include/config-win.h b/include/config-win.h index 53dff5d63af..b30f50f0edb 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -85,6 +85,7 @@ #define LONGLONG_MIN ((__int64) 0x8000000000000000) #define LONGLONG_MAX ((__int64) 0x7FFFFFFFFFFFFFFF) +#define ULONGLONG_MAX ((unsigned __int64) 0xFFFFFFFFFFFFFFFF) #define LL(A) ((__int64) A) /* Type information */ diff --git a/include/my_global.h b/include/my_global.h index 68c331aa414..ca74cb07868 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -606,6 +606,7 @@ extern double my_atof(const char*); /* Some pre-ANSI-C99 systems like AIX 5.1 and Linux/GCC 2.95 define ULONGLONG_MAX, LONGLONG_MIN, LONGLONG_MAX; we use them if they're defined. + Also on Windows we define these constants by hand in config-win.h. */ #if defined(HAVE_LONG_LONG) && !defined(LONGLONG_MIN) From 3248878cf19838198a36401e876e786b72c34d5a Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Fri, 5 Dec 2003 19:20:06 +0300 Subject: [PATCH 22/89] typo fixed --- include/my_global.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index ca74cb07868..bcd6004d72a 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -614,14 +614,14 @@ extern double my_atof(const char*); #define LONGLONG_MAX ((long long) 0x7FFFFFFFFFFFFFFFLL) #endif -#if defined(HAVE_LONG_LONG) && !defined(ULONLONG_MAX) +#if defined(HAVE_LONG_LONG) && !defined(ULONGLONG_MAX) /* First check for ANSI C99 definition: */ #ifdef ULLONG_MAX #define ULONGLONG_MAX ULLONG_MAX #else #define ULONGLONG_MAX ((unsigned long long)(~0ULL)) #endif -#endif /* defined (HAVE_LONG_LONG) && !defined(ULONLONG_MAX)*/ +#endif /* defined (HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)*/ #if SIZEOF_LONG == 4 #define INT_MIN32 (long) 0x80000000L From 431a66e85d68874d5f45d2c487c0d93d6224fce0 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 5 Dec 2003 21:45:19 +0400 Subject: [PATCH 23/89] Fix for #1890 and #1959 This bug happens under Windows & Embedded server Reason is that pthread_self() always returns NULL in this case. This confuses thr_lock function and it doesn't stop thread inserting in the write-locked table. Global problem is that there's no way under Windows to get unique thread handle for working thread. Monty made a workaround for server - we store the thread's handle we get when we create thread in the thread-specific variable. This doesn't work with the embedded library for we don't control thread creation there. I added code that sets CurrentThreadId as the pthread_self for the embedded library. It seems to solve problem because it's unique and we don't use pthread_self as a parameter for thread functions in embedded library. --- mysys/my_thr_init.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 9f64e9dcb60..3196256facc 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -157,6 +157,9 @@ my_bool my_thread_init(void) tmp= &THR_KEY_mysys; #endif tmp->id= ++thread_id; +#if defined(__WIN__) && defined(EMBEDDED_LIBRARY) + tmp->thread_self= (pthread_t)getpid(); +#endif pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST); pthread_cond_init(&tmp->suspend, NULL); tmp->init= 1; From 48317785878fbb31d444629e08deef7212f53906 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Sun, 7 Dec 2003 15:10:21 +0400 Subject: [PATCH 24/89] WL#1175: more default_week_formats for iso compatibility New formats added for 'week()' function and 'default_week_format' option(4 - 7). Next formats is supported now: *Value* *Meaning* `0' Week starts on Sunday; First Sunday of the year starts week 1. Week() returns 0-53. `1' Week starts on Monday; Weeks numbered according to ISO 8601:1988. Week() returns 0-53. `2' Week starts on Sunday; First Sunday of the year starts week 1. Week() returns 1-53. `3' Week starts on Monday; Weeks numbered according to ISO 8601:1988. Week() returns 1-53. `4' Week starts on Sunday; Weeks numbered according to ISO 8601:1988. Week() returns 0-53. `5' Week starts on Monday; First Monday of the year starts week 1. Week() returns 0-53. `6' Week starts on Sunday; Weeks numbered according to ISO 8601:1988. Week() returns 1-53. `7' Week starts on Monday; First Monday of the year starts week 1. Week() returns 1-53. --- mysql-test/r/func_time.result | 27 ++++++++++++-- mysql-test/t/func_time.test | 12 +++++++ sql/item_timefunc.cc | 68 ++++++++++++++++++++++++++--------- sql/mysql_priv.h | 8 +++-- sql/mysqld.cc | 2 +- sql/time.cc | 68 +++++++++++++++++++++++++---------- 6 files changed, 145 insertions(+), 40 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 58a05a2336f..61aa4306c61 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -95,11 +95,34 @@ week(19981231,2) week(19981231,3) week(20000101,2) week(20000101,3) 52 53 52 52 select week(20001231,2),week(20001231,3); week(20001231,2) week(20001231,3) -1 52 +53 52 +select week(19981231,0) as '0', week(19981231,1) as '1', week(19981231,2) as '2', week(19981231,3) as '3', week(19981231,4) as '4', week(19981231,5) as '5', week(19981231,6) as '6', week(19981231,7) as '7'; +0 1 2 3 4 5 6 7 +52 53 52 53 52 52 52 52 +select week(20000101,0) as '0', week(20000101,1) as '1', week(20000101,2) as '2', week(20000101,3) as '3', week(20000101,4) as '4', week(20000101,5) as '5', week(20000101,6) as '6', week(20000101,7) as '7'; +0 1 2 3 4 5 6 7 +0 0 52 52 0 0 52 52 +select week(20000106,0) as '0', week(20000106,1) as '1', week(20000106,2) as '2', week(20000106,3) as '3', week(20000106,4) as '4', week(20000106,5) as '5', week(20000106,6) as '6', week(20000106,7) as '7'; +0 1 2 3 4 5 6 7 +1 1 1 1 1 1 1 1 +select week(20001231,0) as '0', week(20001231,1) as '1', week(20001231,2) as '2', week(20001231,3) as '3', week(20001231,4) as '4', week(20001231,5) as '5', week(20001231,6) as '6', week(20001231,7) as '7'; +0 1 2 3 4 5 6 7 +53 52 53 52 53 52 1 52 +select week(20010101,0) as '0', week(20010101,1) as '1', week(20010101,2) as '2', week(20010101,3) as '3', week(20010101,4) as '4', week(20010101,5) as '5', week(20010101,6) as '6', week(20010101,7) as '7'; +0 1 2 3 4 5 6 7 +0 1 53 1 1 1 1 1 +select yearweek(20001231,0), yearweek(20001231,1), yearweek(20001231,2), yearweek(20001231,3), yearweek(20001231,4), yearweek(20001231,5), yearweek(20001231,6), yearweek(20001231,7); +yearweek(20001231,0) yearweek(20001231,1) yearweek(20001231,2) yearweek(20001231,3) yearweek(20001231,4) yearweek(20001231,5) yearweek(20001231,6) yearweek(20001231,7) +200053 200052 200053 200052 200101 200052 200101 200052 +set default_week_format = 6; +select week(20001231), week(20001231,6); +week(20001231) week(20001231,6) +1 1 +set default_week_format = 0; set default_week_format = 2; select week(20001231),week(20001231,2),week(20001231,0); week(20001231) week(20001231,2) week(20001231,0) -1 1 53 +53 53 53 set default_week_format = 0; select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v'); date_format('1998-12-31','%x-%v') date_format('1999-01-01','%x-%v') diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index a51869e7d76..deb3358da00 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -39,6 +39,18 @@ select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', y select week(19981231,2), week(19981231,3), week(20000101,2), week(20000101,3); select week(20001231,2),week(20001231,3); +select week(19981231,0) as '0', week(19981231,1) as '1', week(19981231,2) as '2', week(19981231,3) as '3', week(19981231,4) as '4', week(19981231,5) as '5', week(19981231,6) as '6', week(19981231,7) as '7'; +select week(20000101,0) as '0', week(20000101,1) as '1', week(20000101,2) as '2', week(20000101,3) as '3', week(20000101,4) as '4', week(20000101,5) as '5', week(20000101,6) as '6', week(20000101,7) as '7'; +select week(20000106,0) as '0', week(20000106,1) as '1', week(20000106,2) as '2', week(20000106,3) as '3', week(20000106,4) as '4', week(20000106,5) as '5', week(20000106,6) as '6', week(20000106,7) as '7'; +select week(20001231,0) as '0', week(20001231,1) as '1', week(20001231,2) as '2', week(20001231,3) as '3', week(20001231,4) as '4', week(20001231,5) as '5', week(20001231,6) as '6', week(20001231,7) as '7'; +select week(20010101,0) as '0', week(20010101,1) as '1', week(20010101,2) as '2', week(20010101,3) as '3', week(20010101,4) as '4', week(20010101,5) as '5', week(20010101,6) as '6', week(20010101,7) as '7'; + +select yearweek(20001231,0), yearweek(20001231,1), yearweek(20001231,2), yearweek(20001231,3), yearweek(20001231,4), yearweek(20001231,5), yearweek(20001231,6), yearweek(20001231,7); + +set default_week_format = 6; +select week(20001231), week(20001231,6); +set default_week_format = 0; + set default_week_format = 2; select week(20001231),week(20001231,2),week(20001231,0); set default_week_format = 0; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index caea79314de..f2b4a041b6c 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -175,27 +175,51 @@ longlong Item_func_second::val_int() } -/* - Returns the week of year. +uint week_mode(uint mode) +{ + uint week_format= (mode & 7); + if (!(week_format & WEEK_MONDAY_FIRST)) + week_format^= WEEK_FIRST_WEEKDAY; + return week_format; +} - The bits in week_format has the following meaning: - 0 If not set: USA format: Sunday is first day of week - If set: ISO format: Monday is first day of week - 1 If not set: Week is in range 0-53 - If set Week is in range 1-53. +/* + The bits in week_format(for calc_week() function) has the following meaning: + WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week + If set Monday is first day of week + WEEK_YEAR (1) If not set Week is in range 0-53 + + Week 0 is returned for the the last week of the previous year (for + a date at start of january) In this case one can get 53 for the + first week of next year. This flag ensures that the week is + relevant for the given year. Note that this flag is only + releveant if WEEK_JANUARY is not set. + + If set Week is in range 1-53. + + In this case one may get week 53 for a date in January (when + the week is that last week of previous year) and week 1 for a + date in December. + + WEEK_FIRST_WEEKDAY (2) If not set Weeks are numbered according + to ISO 8601:1988 + If set The week that contains the first + 'first-day-of-week' is week 1. + + ISO 8601:1988 means that if the week containing January 1 has + four or more days in the new year, then it is week 1; + Otherwise it is the last week of the previous year, and the + next week is week 1. */ longlong Item_func_week::val_int() { uint year; - uint week_format; TIME ltime; if (get_arg0_date(<ime,0)) return 0; - week_format= (uint) args[1]->val_int(); - return (longlong) calc_week(<ime, - (week_format & 2) != 0, - (week_format & 1) == 0, + return (longlong) calc_week(<ime, + week_mode((uint) args[1]->val_int()), &year); } @@ -206,7 +230,9 @@ longlong Item_func_yearweek::val_int() TIME ltime; if (get_arg0_date(<ime,0)) return 0; - week=calc_week(<ime, 1, (args[1]->val_int() & 1) == 0, &year); + week= calc_week(<ime, + (week_mode((uint) args[1]->val_int()) | WEEK_YEAR), + &year); return week+year*100; } @@ -844,7 +870,10 @@ String *Item_func_date_format::val_str(String *str) case 'u': { uint year; - sprintf(intbuff,"%02d",calc_week(&l_time, 0, (*ptr) == 'U', &year)); + sprintf(intbuff,"%02d", + calc_week(&l_time, + ((*ptr) == 'U' ? + WEEK_FIRST_WEEKDAY : WEEK_MONDAY_FIRST) , &year)); str->append(intbuff); } break; @@ -852,7 +881,11 @@ String *Item_func_date_format::val_str(String *str) case 'V': { uint year; - sprintf(intbuff,"%02d",calc_week(&l_time, 1, (*ptr) == 'V', &year)); + sprintf(intbuff,"%02d", + calc_week(&l_time, + ((*ptr) == 'V' ? WEEK_YEAR | WEEK_FIRST_WEEKDAY : + WEEK_YEAR | WEEK_MONDAY_FIRST), + &year)); str->append(intbuff); } break; @@ -860,7 +893,10 @@ String *Item_func_date_format::val_str(String *str) case 'X': { uint year; - (void) calc_week(&l_time, 1, (*ptr) == 'X', &year); + (void) calc_week(&l_time, + ((*ptr) == 'X' ? WEEK_YEAR | WEEK_FIRST_WEEKDAY : + WEEK_YEAR | WEEK_MONDAY_FIRST), + &year); sprintf(intbuff,"%04d",year); str->append(intbuff); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index adb7831896c..04529919990 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -247,6 +247,11 @@ void debug_sync_point(const char* lock_name, uint lock_timeout); #define tmp_file_prefix "#sql" /* Prefix for tmp tables */ #define tmp_file_prefix_length 4 +/* Flags for calc_week() function. */ +#define WEEK_MONDAY_FIRST 1 +#define WEEK_YEAR 2 +#define WEEK_FIRST_WEEKDAY 4 + struct st_table; class THD; @@ -806,8 +811,7 @@ ha_rows filesort(TABLE *form,struct st_sort_field *sortorder, uint s_length, void change_double_for_sort(double nr,byte *to); int get_quick_record(SQL_SELECT *select); int calc_weekday(long daynr,bool sunday_first_day_of_week); -uint calc_week(TIME *ltime, bool with_year, bool sunday_first_day_of_week, - uint *year); +uint calc_week(TIME *l_time, uint week_behaviour, uint *year); void find_date(char *pos,uint *vek,uint flag); TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end); TYPELIB *typelib(List &strings); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e5ddbfe7a33..84287a6cba1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4105,7 +4105,7 @@ this value; if zero (the default): when the size exceeds max_binlog_size. \ "The default week format used by WEEK() functions.", (gptr*) &global_system_variables.default_week_format, (gptr*) &max_system_variables.default_week_format, - 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3L, 0, 1, 0}, + 0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/sql/time.cc b/sql/time.cc index 321a8ba16e5..bf218fa58ab 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -175,42 +175,72 @@ uint calc_days_in_year(uint year) 366 : 365; } -/* Calculate week. If 'with_year' is not set, then return a week 0-53, where - 0 means that it's the last week of the previous year. - If 'with_year' is set then the week will always be in the range 1-53 and - the year out parameter will contain the year for the week */ -uint calc_week(TIME *l_time, bool with_year, bool sunday_first_day_of_week, - uint *year) +/* + The bits in week_format has the following meaning: + WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week + If set Monday is first day of week + WEEK_YEAR (1) If not set Week is in range 0-53 + + Week 0 is returned for the the last week of the previous year (for + a date at start of january) In this case one can get 53 for the + first week of next year. This flag ensures that the week is + relevant for the given year. Note that this flag is only + releveant if WEEK_JANUARY is not set. + + If set Week is in range 1-53. + + In this case one may get week 53 for a date in January (when + the week is that last week of previous year) and week 1 for a + date in December. + + WEEK_FIRST_WEEKDAY (2) If not set Weeks are numbered according + to ISO 8601:1988 + If set The week that contains the first + 'first-day-of-week' is week 1. + + ISO 8601:1988 means that if the week containing January 1 has + four or more days in the new year, then it is week 1; + Otherwise it is the last week of the previous year, and the + next week is week 1. +*/ + +uint calc_week(TIME *l_time, uint week_behaviour, uint *year) { uint days; ulong daynr=calc_daynr(l_time->year,l_time->month,l_time->day); ulong first_daynr=calc_daynr(l_time->year,1,1); - uint weekday=calc_weekday(first_daynr,sunday_first_day_of_week); + bool monday_first= test(week_behaviour & WEEK_MONDAY_FIRST); + bool week_year= test(week_behaviour & WEEK_YEAR); + bool first_weekday= test(week_behaviour & WEEK_FIRST_WEEKDAY); + + uint weekday=calc_weekday(first_daynr, !monday_first); *year=l_time->year; - if (l_time->month == 1 && l_time->day <= 7-weekday && - ((!sunday_first_day_of_week && weekday >= 4) || - (sunday_first_day_of_week && weekday != 0))) + + if (l_time->month == 1 && l_time->day <= 7-weekday) { - /* Last week of the previous year */ - if (!with_year) + if (!week_year && + (first_weekday && weekday != 0 || + !first_weekday && weekday >= 4)) return 0; - with_year=0; // Don't check the week again + week_year= 1; (*year)--; first_daynr-= (days=calc_days_in_year(*year)); weekday= (weekday + 53*7- days) % 7; } - if ((sunday_first_day_of_week && weekday != 0) || - (!sunday_first_day_of_week && weekday >= 4)) + + if ((first_weekday && weekday != 0) || + (!first_weekday && weekday >= 4)) days= daynr - (first_daynr+ (7-weekday)); else days= daynr - (first_daynr - weekday); - if (with_year && days >= 52*7) + + if (week_year && days >= 52*7) { - /* Check if we are on the first week of the next year (or week 53) */ weekday= (weekday + calc_days_in_year(*year)) % 7; - if (weekday < 4) - { // We are at first week on next year + if (!first_weekday && weekday < 4 || + first_weekday && weekday == 0) + { (*year)++; return 1; } From dba12258b9e60ece0917b6907c5e07a2a1b62727 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Mon, 8 Dec 2003 16:18:25 +0100 Subject: [PATCH 25/89] Fix for BUG#2045 "Sending SIGHUP to mysqld crashes it if running with --log-bin". The constructor of Rotate_log_event used when we are rotating our binlog or relay log, should not assume that there is a nonzero THD available. For example, when we are reacting to SIGHUP, the THD is 0. In fact we don't need to use the THD in this constructor; we can do like for Stop_log_event, and use the minimal Log_event constructor. If we were allowed to put Unix-specific commands in the testsuite, I'd add a test for this (). --- sql/log.cc | 4 ++-- sql/log_event.cc | 7 ++++++- sql/log_event.h | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index e6eaa3b802c..8bd42d28e59 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -843,7 +843,7 @@ void MYSQL_LOG::new_file(bool need_lock) We log the whole file name for log file as the user may decide to change base names at some point. */ - THD* thd = current_thd; + THD* thd = current_thd; /* may be 0 if we are reacting to SIGHUP */ Rotate_log_event r(thd,new_name+dirname_length(new_name)); r.set_log_pos(this); @@ -852,7 +852,7 @@ void MYSQL_LOG::new_file(bool need_lock) the slave running with log-bin, we set the flag on rotate event to prevent infinite log rotation loop */ - if (thd->slave_thread) + if (thd && thd->slave_thread) r.flags|= LOG_EVENT_FORCED_ROTATE_F; r.write(&log_file); bytes_written += r.get_event_len(); diff --git a/sql/log_event.cc b/sql/log_event.cc index d17c94a2b44..9779b7401dd 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -128,7 +128,12 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans) (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))); } - +/* + This minimal constructor is for when you are not even sure that there is a + valid THD. For example in the server when we are shutting down or flushing + logs after receiving a SIGHUP (then we must write a Rotate to the binlog but + we have no THD, so we need this minimal constructor). +*/ Log_event::Log_event() :temp_buf(0), exec_time(0), cached_event_len(0), flags(0), cache_stmt(0), thd(0) diff --git a/sql/log_event.h b/sql/log_event.h index 929d550951e..a1a7798be34 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -607,7 +607,7 @@ public: Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg, uint ident_len_arg = 0, ulonglong pos_arg = LOG_EVENT_OFFSET) - :Log_event(thd_arg,0,0), new_log_ident(new_log_ident_arg), + :Log_event(), new_log_ident(new_log_ident_arg), pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg : (uint) strlen(new_log_ident_arg)), alloced(0) {} From 56e49fd735c97e98bc50235e50bc456e99824c83 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Mon, 8 Dec 2003 20:53:46 +0100 Subject: [PATCH 26/89] Create PID file with O_TRUNC, so that it is emptied before it is written to. Otherwise, if the previous run ended with a crash, and the PID was 1234, and you have rebooted the machine and the new PID is 99 then in the PID file you will have 9934. Note: users of mysqld_safe did not have the problem because this script deletes the PID file before starting mysqld. --- sql/mysqld.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index daccfc52af4..9c68ae95ef2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1461,7 +1461,8 @@ static void start_signal_handler(void) if (!opt_bootstrap) { File pidFile; - if ((pidFile = my_create(pidfile_name,0664, O_WRONLY, MYF(MY_WME))) >= 0) + if ((pidFile = my_create(pidfile_name,0664, + O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0) { char buff[21]; sprintf(buff,"%lu",(ulong) getpid()); @@ -1754,7 +1755,8 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) if (!opt_bootstrap) { File pidFile; - if ((pidFile = my_create(pidfile_name,0664, O_WRONLY, MYF(MY_WME))) >= 0) + if ((pidFile = my_create(pidfile_name,0664, + O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0) { char buff[21]; sprintf(buff,"%lu",(ulong) getpid()); From 34b101cadfa3816f6392653f22993722adbb894f Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Tue, 9 Dec 2003 12:36:57 +0400 Subject: [PATCH 27/89] Fix for the bug #1885: mysqldump does not dumps timestamp default. --- sql/sql_parse.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c867112bb2a..fc9c21586d9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3042,7 +3042,12 @@ bool add_field_to_list(char *field_name, enum_field_types type, if (default_value) { - if (default_value->type() == Item::NULL_ITEM) + if (type == FIELD_TYPE_TIMESTAMP) + { + net_printf(&thd->net, ER_INVALID_DEFAULT, field_name); + DBUG_RETURN(1); + } + else if (default_value->type() == Item::NULL_ITEM) { default_value=0; if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == From 9428000f4629581082c524f749e88f8b7feae1ab Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Tue, 9 Dec 2003 12:59:00 +0400 Subject: [PATCH 28/89] test for the bug #1885: mysqldump does not dumps timestamp default. --- mysql-test/r/type_timestamp.result | 2 ++ mysql-test/t/type_timestamp.test | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 9403b73d459..b513f958787 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -122,3 +122,5 @@ t2 t4 t6 t8 t10 t12 t14 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 drop table t1; +create table t1 (a timestamp default 1); +Invalid default value for 'a' diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index 0c88f1b8025..17f7b7c487f 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -72,3 +72,9 @@ set new=1; select * from t1; drop table t1; +# +# Bug #1885 +# + +--error 1067 +create table t1 (a timestamp default 1); From ab1c17b9436d07ba9c92b4a24303d10a22b4528a Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Tue, 9 Dec 2003 17:33:29 +0400 Subject: [PATCH 29/89] Fix for the bugs: #2005 Long decimal comparion bug. #2055 mysqldump should replace "-inf" numeric field values with "NULL" --- client/mysqldump.c | 34 +++++++++++++++++++++++++++++----- mysql-test/t/mysqldump.test | 19 +++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 40f88021c89..7092503fa25 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1067,10 +1067,22 @@ static void dumpTable(uint numFields, char *table) } else { - /* change any strings ("inf","nan",..) into NULL */ + /* change any strings ("inf", "-inf", "nan") into NULL */ char *ptr = row[i]; - dynstr_append(&extended_row, - (!isalpha(*ptr)) ? ptr : "NULL"); + if (isalpha(*ptr) || (*ptr == '-' && *(ptr+1) == 'i')) + dynstr_append(&extended_row, "NULL"); + else + { + if (field->type == FIELD_TYPE_DECIMAL) + { + /* add " signs around */ + dynstr_append(&extended_row, "\""); + dynstr_append(&extended_row, ptr); + dynstr_append(&extended_row, "\""); + } + else + dynstr_append(&extended_row, ptr); + } } } else @@ -1098,13 +1110,25 @@ static void dumpTable(uint numFields, char *table) } else { - /* change any strings ("inf","nan",..) into NULL */ + /* change any strings ("inf", "-inf", "nan") into NULL */ char *ptr = row[i]; if (opt_xml) fprintf(md_result_file, "\t\t%s\n", field->name,!isalpha(*ptr) ?ptr: "NULL"); + else if (isalpha(*ptr) || (*ptr == '-' && *(ptr+1) == 'i')) + fputs("NULL", md_result_file); else - fputs((!isalpha(*ptr)) ? ptr : "NULL", md_result_file); + { + if (field->type == FIELD_TYPE_DECIMAL) + { + /* add " signs around */ + fputs("\"", md_result_file); + fputs(ptr, md_result_file); + fputs("\"", md_result_file); + } + else + fputs(ptr, md_result_file); + } } } else diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index c98fd4050f2..87363855db0 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -8,3 +8,22 @@ CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); --exec $MYSQL_DUMP -X test t1 DROP TABLE t1; + +# +# Bug #2005 +# + +CREATE TABLE t1 (a decimal(240, 20)); +INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), +("0987654321098765432109876543210987654321"); +--exec $MYSQL_DUMP test t1 +DROP TABLE t1; + +# +# Bug #2055 +# + +CREATE TABLE t1 (a double); +INSERT INTO t1 VALUES (-9e999999); +--exec $MYSQL_DUMP test t1 +DROP TABLE t1; From 0fb5cf70e5f633932bb86ba3ce7a2b644340a2f9 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Tue, 9 Dec 2003 16:21:23 +0200 Subject: [PATCH 30/89] Don't limit number of tables in table cache --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index daccfc52af4..751cfe7473c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4067,7 +4067,7 @@ this value; if zero (the default): when the size exceeds max_binlog_size. \ 1, 0}, {"table_cache", OPT_TABLE_CACHE, "The number of open tables for all threads.", (gptr*) &table_cache_size, - (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 16384, 0, 1, + (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, ~0L, 0, 1, 0}, {"thread_concurrency", OPT_THREAD_CONCURRENCY, "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.", From e82018e34f6be6824ec72b461a472250c2acdb47 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Tue, 9 Dec 2003 20:17:28 +0200 Subject: [PATCH 31/89] Add newline after pid in pidfile --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3c196eddb47..70ee2f632ca 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1465,7 +1465,7 @@ static void start_signal_handler(void) O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0) { char buff[21]; - sprintf(buff,"%lu",(ulong) getpid()); + sprintf(buff,"%lu\n",(ulong) getpid()); (void) my_write(pidFile, buff,strlen(buff),MYF(MY_WME)); (void) my_close(pidFile,MYF(0)); } From eaa0c4494fc799707213c2cbf5a7b3114dd0e4e8 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 9 Dec 2003 20:49:48 +0100 Subject: [PATCH 32/89] code cleanup after some reasoning --- libmysql/libmysql.c | 3 ++- myisam/ft_boolean_search.c | 11 +++++++++-- sql/mysqld.cc | 4 ++-- sql/opt_range.cc | 2 +- sql/repl_failsafe.cc | 1 - sql/table.cc | 5 ++--- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 6abc29d29f4..5fcc3ba5ee0 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -941,7 +941,8 @@ static void mysql_read_default_options(struct st_mysql_options *options, options->rpl_parse= 1; break; case 27: - options->max_allowed_packet= atoi(opt_arg); + if (opt_arg) + options->max_allowed_packet= atoi(opt_arg); break; default: DBUG_PRINT("warning",("unknown option: %s",option[0])); diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index 30b52a20060..c7128464228 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -322,10 +322,13 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, to alloc queue with alloc_root() */ res=ftb->queue.max_elements=1+query_len/(min(ft_min_word_len,2)+1); - ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*)); + if (!(ftb->queue.root= + (byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*)))) + goto err; reinit_queue(& ftb->queue, res, 0, 0, (int (*)(void*,byte*,byte*))FTB_WORD_cmp, 0); - ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)); + if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)))) + goto err; ftbe->weight=1; ftbe->flags=FTB_FLAG_YES; ftbe->nos=1; @@ -343,6 +346,10 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC; ftb->state=READY; return ftb; +err: + free_root(& ftb->mem_root, MYF(0)); + my_free((gptr)ftb,MYF(0)); + return 0; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2e87ade9174..806a3524191 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4632,14 +4632,14 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), my_use_symdir=0; break; case (int) OPT_BIND_ADDRESS: - if (argument && isdigit(argument[0])) + if (isdigit(argument[0])) { my_bind_addr = (ulong) inet_addr(argument); } else { struct hostent *ent; - if (argument || argument[0]) + if (argument[0]) ent=gethostbyname(argument); else { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 63850709285..07f2f1eaf67 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2454,7 +2454,7 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) if (cp_buffer_from_ref(ref)) { if (thd->fatal_error) - return 0; // out of memory + goto err; // out of memory return quick; // empty range } diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 6b91d81b487..6599516044a 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -426,7 +426,6 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, my_snprintf(errmsg, SLAVE_ERRMSG_SIZE, "Could not find slave event in log '%s'", (char*)log_file_name); - delete ev; return 0; } diff --git a/sql/table.cc b/sql/table.cc index 422202301f1..0789f7469e7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1100,13 +1100,12 @@ rename_file_ext(const char * from,const char * to,const char * ext) char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) { Field *field=table->field[fieldnr]; - char buff[MAX_FIELD_WIDTH]; + char buff[MAX_FIELD_WIDTH], *to; String str(buff,sizeof(buff)); field->val_str(&str,&str); uint length=str.length(); - if (!length) + if (!length || !(to= (char*) alloc_root(mem,length+1))) return NullS; - char *to= (char*) alloc_root(mem,length+1); memcpy(to,str.ptr(),(uint) length); to[length]=0; return to; From 5fa5a8df4ea5aa509e876eecec3e52b49ac24750 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Tue, 9 Dec 2003 23:52:58 +0300 Subject: [PATCH 33/89] Fix for bug #1335: filesort is missing in EXPLAIN if ORDER BY NULL is used --- mysql-test/r/group_by.result | 17 ++++++++++++++++- mysql-test/t/group_by.test | 28 ++++++++++++++++++++++++++++ sql/sql_select.cc | 14 ++++++++++++-- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index f89cb8a6792..861f0f009cd 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -287,7 +287,7 @@ table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 8 Using filesort explain select sql_big_result spid,sum(userid) from t1 group by spid desc order by null; table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 8 +t1 ALL NULL NULL NULL NULL 8 Using filesort select sql_big_result spid,sum(userid) from t1 group by spid desc; spid sum(userid) 7 3 @@ -597,3 +597,18 @@ count(*) category 1 3 1 4 drop table t1; +userid count(*) +3 5 +2 1 +1 2 +EXPLAIN SELECT userid,count(*) FROM t1 GROUP BY userid DESC; +table type possible_keys key key_len ref rows Extra +t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort +i COUNT(DISTINCT(i)) +1 1 +2 1 +4 4 +explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; +table type possible_keys key key_len ref rows Extra +t1 ALL NULL NULL NULL NULL 6 Using filesort +DROP TABLE t1; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index df99bc2a9dc..d28eeb27c15 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -423,3 +423,31 @@ select id, sum(qty) as sqty, count(qty) as cqty from t1 group by id having sum(q select count(*), case interval(qty,2,3,4,5,6,7,8) when -1 then NULL when 0 then "zero" when 1 then "one" when 2 then "two" end as category from t1 group by category; select count(*), interval(qty,2,3,4,5,6,7,8) as category from t1 group by category; drop table t1; +# +# Tests for bug #1355: 'Using filesort' is missing in EXPLAIN when ORDER BY +# NULL is used. +# +--disable_query_log +CREATE TABLE t1 ( + userid int(10) unsigned, + score smallint(5) unsigned, + key (score) +); +INSERT INTO t1 VALUES (1,1),(2,2),(1,1),(3,3),(3,3),(3,3),(3,3),(3,3); +# Here we select unordered GROUP BY into a temporary talbe, +# and then sort it with filesort (GROUP BY in MySQL +# implies sorted order of results) +SELECT userid,count(*) FROM t1 GROUP BY userid DESC; +--enable_query_log +EXPLAIN SELECT userid,count(*) FROM t1 GROUP BY userid DESC; +--disable_query_log +DROP TABLE t1; +CREATE TABLE t1 ( + i int(11) default NULL, + j int(11) default NULL +); +INSERT INTO t1 VALUES (1,2),(2,3),(4,5),(3,5),(1,5),(23,5); +SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; +--enable_query_log +explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; +DROP TABLE t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7f8dfd219d0..df4b0226ff6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -696,8 +696,18 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (select_options & SELECT_DESCRIBE) { - if (!order && !no_order) - order=group; + /* + Check if we managed to optimize ORDER BY away and don't use temporary + table to resolve ORDER BY: in that case, we only may need to do + filesort for GROUP BY. + */ + if (!order && !no_order && (!skip_sort_order || !need_tmp)) + { + /* Reset 'order' to 'group' and reinit variables describing 'order' */ + order= group; + simple_order= simple_group; + skip_sort_order= 0; + } if (order && (join.const_tables == join.tables || ((simple_order || skip_sort_order) && From 0dea4148c821d5d7fe9ad2eb15e50120fe6c44c2 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 9 Dec 2003 21:56:11 +0100 Subject: [PATCH 34/89] followup --- sql/opt_range.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 07f2f1eaf67..4bbeaca8a79 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2447,6 +2447,7 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) QUICK_SELECT *quick=new QUICK_SELECT(thd, table, ref->key, 1); KEY *key_info = &table->key_info[ref->key]; KEY_PART *key_part; + QUICK_RANGE *range; uint part; if (!quick) @@ -2458,8 +2459,7 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) return quick; // empty range } - QUICK_RANGE *range= new QUICK_RANGE(); - if (!range) + if (!(range= new QUICK_RANGE())) goto err; // out of memory range->min_key=range->max_key=(char*) ref->key_buff; From 6a95123971edb494e33330ed51d00a369293c60e Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Wed, 10 Dec 2003 00:00:20 +0200 Subject: [PATCH 35/89] Added checking of return value from my_once_alloc() in charset Added checking of return value from malloc() in reg_init() --- client/mysqltest.c | 1 + dbug/dbug.c | 2 +- mysys/charset.c | 52 +++++++++++++++++++++++++++++++++------------ regex/reginit.c | 10 +++++++++ sql/item_strfunc.cc | 4 ++++ 5 files changed, 54 insertions(+), 15 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index fd1c928b4fd..a168099e6d6 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2302,6 +2302,7 @@ static VAR* var_init(VAR* v, const char* name, int name_len, const char* val, if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME)))) die("Out of memory"); + /* 'name' may be NULL here, but in this case name_len is 0 */ memcpy(tmp_var->name, name, name_len); if (val) { diff --git a/dbug/dbug.c b/dbug/dbug.c index a4f9d5ecd4b..c6df6b105c5 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -501,7 +501,7 @@ void _db_push_ (const char *control) if (! _db_fp_) _db_fp_= stderr; /* Output stream, default stderr */ - if (control && *control == '-') + if (*control == '-') { if (*++control == '#') control++; diff --git a/mysys/charset.c b/mysys/charset.c index ba6733185e0..5e5be9e1b42 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -300,7 +300,25 @@ static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, return NULL; } -static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name, myf flags) +/* + Read charset from file. + + NOTES + One never has to deallocate character sets. They will all be deallocated + by my_once_free() when program ends. + + If my_once_alloc() fails then this function may 'leak' some memory + which my_once_free() will deallocate, but this is so unlikely to happen + that this can be ignored. + + RETURN + 0 Error + # Pointer to allocated charset structure +*/ + + +static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name, + myf flags) { CHARSET_INFO tmp_cs,*cs; uchar tmp_ctype[CTYPE_TABLE_SIZE]; @@ -317,21 +335,27 @@ static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name, myf flags) cs->sort_order=tmp_sort_order; cs->strxfrm_multiply=cs->mbmaxlen=1; if (read_charset_file(cs_number, cs, flags)) - return NULL; + return 0; - cs = (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO), - MYF(MY_WME)); - *cs=tmp_cs; - cs->name = (char *) my_once_alloc((uint) strlen(cs_name)+1, MYF(MY_WME)); - cs->ctype = (uchar*) my_once_alloc(CTYPE_TABLE_SIZE, MYF(MY_WME)); - cs->to_lower = (uchar*) my_once_alloc(TO_LOWER_TABLE_SIZE, MYF(MY_WME)); - cs->to_upper = (uchar*) my_once_alloc(TO_UPPER_TABLE_SIZE, MYF(MY_WME)); + if (!(cs= (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO), + MYF(MY_WME)))) + return 0; + + *cs= tmp_cs; + cs->name= (char *) my_once_alloc((uint) strlen(cs_name)+1, MYF(MY_WME)); + cs->ctype= (uchar*) my_once_alloc(CTYPE_TABLE_SIZE, MYF(MY_WME)); + cs->to_lower= (uchar*) my_once_alloc(TO_LOWER_TABLE_SIZE, MYF(MY_WME)); + cs->to_upper= (uchar*) my_once_alloc(TO_UPPER_TABLE_SIZE, MYF(MY_WME)); cs->sort_order=(uchar*) my_once_alloc(SORT_ORDER_TABLE_SIZE, MYF(MY_WME)); - cs->number = cs_number; - memcpy((char*) cs->name, (char*) cs_name, strlen(cs_name) + 1); - memcpy((char*) cs->ctype, (char*) tmp_ctype, sizeof(tmp_ctype)); - memcpy((char*) cs->to_lower, (char*) tmp_to_lower, sizeof(tmp_to_lower)); - memcpy((char*) cs->to_upper, (char*) tmp_to_upper, sizeof(tmp_to_upper)); + if (!cs->name || !cs->ctype || !cs->to_lower || !cs->to_upper || + !cs->sort_order) + return 0; + + cs->number= cs_number; + memcpy((char*) cs->name, (char*) cs_name, strlen(cs_name) + 1); + memcpy((char*) cs->ctype, (char*) tmp_ctype, sizeof(tmp_ctype)); + memcpy((char*) cs->to_lower, (char*) tmp_to_lower, sizeof(tmp_to_lower)); + memcpy((char*) cs->to_upper, (char*) tmp_to_upper, sizeof(tmp_to_upper)); memcpy((char*) cs->sort_order, (char*) tmp_sort_order, sizeof(tmp_sort_order)); insert_dynamic(&cs_info_table, (gptr) &cs); diff --git a/regex/reginit.c b/regex/reginit.c index 18647c386fc..309685fadf2 100644 --- a/regex/reginit.c +++ b/regex/reginit.c @@ -49,6 +49,16 @@ void regex_init() for (i=0; i < CCLASS_LAST ; i++) { char *tmp=(char*) malloc(count[i]+1); + if (!tmp) + { + /* + This is very unlikely to happen as this function is called once + at program startup + */ + fprintf(stderr, + "Fatal error: Can't allocate memory in regex_init\n"); + exit(1); + } memcpy(tmp,buff[i],count[i]*sizeof(char)); tmp[count[i]]=0; cclasses[i].chars=tmp; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index dd1ec6bd2da..40b18755744 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2043,6 +2043,10 @@ String* Item_func_export_set::val_str(String* str) null_value=1; return 0; } + /* + Arg count can only be 3, 4 or 5 here. This is guaranteed from the + grammar for EXPORT_SET() + */ switch(arg_count) { case 5: num_set_values = (uint) args[4]->val_int(); From 25a0bfb268609c662f8dea1ae7f640675c7a563d Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Wed, 10 Dec 2003 01:08:10 +0300 Subject: [PATCH 36/89] bug #1335 tests followup: --disable_query_log was not a good idea, Serg says --- mysql-test/r/group_by.result | 14 ++++++++++++++ mysql-test/t/group_by.test | 4 ---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 861f0f009cd..dba95614052 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -597,6 +597,13 @@ count(*) category 1 3 1 4 drop table t1; +CREATE TABLE t1 ( +userid int(10) unsigned, +score smallint(5) unsigned, +key (score) +); +INSERT INTO t1 VALUES (1,1),(2,2),(1,1),(3,3),(3,3),(3,3),(3,3),(3,3); +SELECT userid,count(*) FROM t1 GROUP BY userid DESC; userid count(*) 3 5 2 1 @@ -604,6 +611,13 @@ userid count(*) EXPLAIN SELECT userid,count(*) FROM t1 GROUP BY userid DESC; table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort +DROP TABLE t1; +CREATE TABLE t1 ( +i int(11) default NULL, +j int(11) default NULL +); +INSERT INTO t1 VALUES (1,2),(2,3),(4,5),(3,5),(1,5),(23,5); +SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; i COUNT(DISTINCT(i)) 1 1 2 1 diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index d28eeb27c15..58bb4b3e268 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -427,7 +427,6 @@ drop table t1; # Tests for bug #1355: 'Using filesort' is missing in EXPLAIN when ORDER BY # NULL is used. # ---disable_query_log CREATE TABLE t1 ( userid int(10) unsigned, score smallint(5) unsigned, @@ -438,9 +437,7 @@ INSERT INTO t1 VALUES (1,1),(2,2),(1,1),(3,3),(3,3),(3,3),(3,3),(3,3); # and then sort it with filesort (GROUP BY in MySQL # implies sorted order of results) SELECT userid,count(*) FROM t1 GROUP BY userid DESC; ---enable_query_log EXPLAIN SELECT userid,count(*) FROM t1 GROUP BY userid DESC; ---disable_query_log DROP TABLE t1; CREATE TABLE t1 ( i int(11) default NULL, @@ -448,6 +445,5 @@ CREATE TABLE t1 ( ); INSERT INTO t1 VALUES (1,2),(2,3),(4,5),(3,5),(1,5),(23,5); SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; ---enable_query_log explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; DROP TABLE t1; From cfeec4f58e549a33e3e77c9fbfc48c09dc975cd3 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Wed, 10 Dec 2003 12:03:54 +0200 Subject: [PATCH 37/89] Add cast to remove compiler warning --- sql/sql_cache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 8610fcb8f22..63d4e4222b4 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2181,7 +2181,7 @@ void Query_cache::free_memory_block(Query_cache_block *block) block->type= Query_cache_block::FREE; // mark block as free in any case DBUG_PRINT("qcache", ("first_block 0x%lx, block 0x%lx, pnext 0x%lx pprev 0x%lx", - (ulong) first_block, (ulong) block,block->pnext, + (ulong) first_block, (ulong) block, (ulong) block->pnext, (ulong) block->pprev)); if (block->pnext != first_block && block->pnext->is_free()) From d04b02b97727640b4ecfe58eb96d9a30276b7a77 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Wed, 10 Dec 2003 15:17:23 +0300 Subject: [PATCH 38/89] followup to fix for bug #1790 BIT_AND() result in GROUP BY different when SQL_BIG_RESULT used": now BIT_AND() always returns 18446744073709551615 if no rows were found. This patch also fixes bug #1972: "BIT_AND() and BIT_OR() still return a *signed* 64bit value" --- mysql-test/r/func_group.result | 23 +++++++++++++++++------ mysql-test/t/func_group.test | 8 ++++++++ sql/item_sum.cc | 9 +++++---- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index f6a30813bb0..99c42bb83cf 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -207,13 +207,13 @@ drop table t1,t2; CREATE TABLE t1 (a int, b int); select count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1; count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -0 NULL NULL NULL NULL NULL -1 0 +0 NULL NULL NULL NULL NULL 18446744073709551615 0 select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) insert into t1 values (1,null); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL -1 0 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 insert into t1 values (1,null); insert into t1 values (2,null); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; @@ -222,8 +222,8 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) 2 0 NULL NULL NULL NULL NULL 18446744073709551615 0 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL -1 0 -2 0 NULL NULL NULL NULL NULL -1 0 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 +2 0 NULL NULL NULL NULL NULL 18446744073709551615 0 insert into t1 values (2,1); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) @@ -231,7 +231,7 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) 2 1 1 1.0000 0.0000 1 1 1 1 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL -1 0 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 2 1 1 1.0000 0.0000 1 1 1 1 insert into t1 values (3,1); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; @@ -241,7 +241,18 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) 3 1 1 1.0000 0.0000 1 1 1 1 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL -1 0 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 2 1 1 1.0000 0.0000 1 1 1 1 3 1 1 1.0000 0.0000 1 1 1 1 drop table t1; +create table t1 (col int); +insert into t1 values (-1), (-2), (-3); +select bit_and(col), bit_or(col) from t1; +bit_and(col) bit_or(col) +18446744073709551612 18446744073709551615 +select SQL_BIG_RESULT bit_and(col), bit_or(col) from t1 group by col; +bit_and(col) bit_or(col) +18446744073709551613 18446744073709551613 +18446744073709551614 18446744073709551614 +18446744073709551615 18446744073709551615 +drop table t1; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 40d829d3e70..d03e4b9b629 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -147,3 +147,11 @@ insert into t1 values (3,1); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; drop table t1; +# +# Bug #1972: test for bit_and(), bit_or() and negative values +# +create table t1 (col int); +insert into t1 values (-1), (-2), (-3); +select bit_and(col), bit_or(col) from t1; +select SQL_BIG_RESULT bit_and(col), bit_or(col) from t1 group by col; +drop table t1; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 5a5934db0cd..e18fa83e49d 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -104,12 +104,13 @@ Item_sum_num::val_str(String *str) String * Item_sum_int::val_str(String *str) { - longlong nr=val_int(); + longlong nr= val_int(); if (null_value) return 0; - char buff[21]; - uint length= (uint) (longlong10_to_str(nr,buff,-10)-buff); - str->copy(buff,length); + if (unsigned_flag) + str->set((ulonglong) nr); + else + str->set(nr); return str; } From 194da99215cc7d0214415cb4f484f0f4176e4d5f Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Wed, 10 Dec 2003 17:53:55 +0400 Subject: [PATCH 39/89] Fix for bug# 1142 ./configure - error in file causes failure of compile (SSL option needed) --- acinclude.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 146f1d18afb..75fb8320709 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -745,7 +745,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \ /usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do - if test -f $d/libssl.a || test -f $d/libssl.dylib ; then + if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl.dylib ; then OPENSSL_LIB=$d fi done @@ -757,7 +757,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ if test -f $incs/openssl/ssl.h ; then OPENSSL_INCLUDE=-I$incs fi - if test -f $libs/libssl.a || test -f $d/libssl.dylib ; then + if test -f $libs/libssl.a || test -f $libs/libssl.so || test -f $libs/libssl.dylib ; then OPENSSL_LIB=$libs fi ;; From 38c454b0e45de51652fb2fdd71a392aa336b21fa Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Wed, 10 Dec 2003 17:30:37 +0300 Subject: [PATCH 40/89] fix for bug #1993 'bit functions do not return unsigned values' introduced base class Item_func_bit for bit functions --- mysql-test/r/func_op.result | 18 ++++++++++++++++ mysql-test/t/func_op.test | 9 ++++++++ sql/item_func.h | 42 ++++++++++++++++++++----------------- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/func_op.result b/mysql-test/r/func_op.result index 9f49b5809df..d009a66353e 100644 --- a/mysql-test/r/func_op.result +++ b/mysql-test/r/func_op.result @@ -7,3 +7,21 @@ select 1 | (1+1),5 & 3,bit_count(7) ; select 1 << 32,1 << 63, 1 << 64, 4 >> 2, 4 >> 63, 1<< 63 >> 60; 1 << 32 1 << 63 1 << 64 4 >> 2 4 >> 63 1<< 63 >> 60 4294967296 9223372036854775808 0 1 0 8 +select -1 | 0, -1 ^ 0, -1 & 0; +-1 | 0 -1 ^ 0 -1 & 0 +18446744073709551615 18446744073709551615 0 +select -1 | 1, -1 ^ 1, -1 & 1; +-1 | 1 -1 ^ 1 -1 & 1 +18446744073709551615 18446744073709551614 1 +select 1 | -1, 1 ^ -1, 1 & -1; +1 | -1 1 ^ -1 1 & -1 +18446744073709551615 18446744073709551614 1 +select 0 | -1, 0 ^ -1, 0 & -1; +0 | -1 0 ^ -1 0 & -1 +18446744073709551615 18446744073709551615 0 +select -1 >> 0, -1 << 0; +-1 >> 0 -1 << 0 +18446744073709551615 18446744073709551615 +select -1 >> 1, -1 << 1; +-1 >> 1 -1 << 1 +9223372036854775807 18446744073709551614 diff --git a/mysql-test/t/func_op.test b/mysql-test/t/func_op.test index 778c8406b8d..a312d6ac8c0 100644 --- a/mysql-test/t/func_op.test +++ b/mysql-test/t/func_op.test @@ -5,3 +5,12 @@ select 1+1,1-1,1+1*2,8/5,8%5,mod(8,5),mod(8,5)|0,-(1+1)*-2; select 1 | (1+1),5 & 3,bit_count(7) ; select 1 << 32,1 << 63, 1 << 64, 4 >> 2, 4 >> 63, 1<< 63 >> 60; +# +# bug #1993: bit functions must be unsigned +# +select -1 | 0, -1 ^ 0, -1 & 0; +select -1 | 1, -1 ^ 1, -1 & 1; +select 1 | -1, 1 ^ -1, 1 & -1; +select 0 | -1, 0 ^ -1, 0 & -1; +select -1 >> 0, -1 << 0; +select -1 >> 1, -1 << 1; diff --git a/sql/item_func.h b/sql/item_func.h index 09aba9694dd..4d171cda490 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -642,23 +642,30 @@ public: unsigned int size_of() { return sizeof(*this);} }; +/* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */ -class Item_func_bit_or :public Item_int_func +class Item_func_bit: public Item_int_func { public: - Item_func_bit_or(Item *a,Item *b) :Item_int_func(a,b) {} - longlong val_int(); - const char *func_name() const { return "|"; } - void fix_length_and_dec() { unsigned_flag=1; } + Item_func_bit(Item *a, Item *b) :Item_int_func(a, b) {} + Item_func_bit(Item *a) :Item_int_func(a) {} + void fix_length_and_dec() { unsigned_flag= 1; } }; -class Item_func_bit_and :public Item_int_func +class Item_func_bit_or :public Item_func_bit { public: - Item_func_bit_and(Item *a,Item *b) :Item_int_func(a,b) {} + Item_func_bit_or(Item *a, Item *b) :Item_func_bit(a, b) {} + longlong val_int(); + const char *func_name() const { return "|"; } +}; + +class Item_func_bit_and :public Item_func_bit +{ +public: + Item_func_bit_and(Item *a, Item *b) :Item_func_bit(a, b) {} longlong val_int(); const char *func_name() const { return "&"; } - void fix_length_and_dec() { unsigned_flag=1; } }; class Item_func_bit_count :public Item_int_func @@ -670,30 +677,28 @@ public: void fix_length_and_dec() { max_length=2; } }; -class Item_func_shift_left :public Item_int_func +class Item_func_shift_left :public Item_func_bit { public: - Item_func_shift_left(Item *a,Item *b) :Item_int_func(a,b) {} + Item_func_shift_left(Item *a, Item *b) :Item_func_bit(a, b) {} longlong val_int(); const char *func_name() const { return "<<"; } - void fix_length_and_dec() { unsigned_flag=1; } }; -class Item_func_shift_right :public Item_int_func +class Item_func_shift_right :public Item_func_bit { public: - Item_func_shift_right(Item *a,Item *b) :Item_int_func(a,b) {} + Item_func_shift_right(Item *a, Item *b) :Item_func_bit(a, b) {} longlong val_int(); const char *func_name() const { return ">>"; } }; -class Item_func_bit_neg :public Item_int_func +class Item_func_bit_neg :public Item_func_bit { public: - Item_func_bit_neg(Item *a) :Item_int_func(a) {} + Item_func_bit_neg(Item *a) :Item_func_bit(a) {} longlong val_int(); const char *func_name() const { return "~"; } - void fix_length_and_dec() { unsigned_flag=1; } }; class Item_func_set_last_insert_id :public Item_int_func @@ -1018,13 +1023,12 @@ enum Item_cast Item *create_func_cast(Item *a, Item_cast cast_type); -class Item_func_bit_xor : public Item_int_func +class Item_func_bit_xor : public Item_func_bit { public: - Item_func_bit_xor(Item *a,Item *b) :Item_int_func(a,b) {} + Item_func_bit_xor(Item *a, Item *b) :Item_func_bit(a, b) {} longlong val_int(); const char *func_name() const { return "^"; } - void fix_length_xor_dec() { unsigned_flag=1; } }; class Item_func_is_free_lock :public Item_int_func From 007fea7203bc34c9c5f1d80eb47706f1f7c19728 Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Wed, 10 Dec 2003 18:41:13 +0400 Subject: [PATCH 41/89] proper musqldump test result (in addition to CS 1.1623 03/12/09) --- mysql-test/r/mysqldump.result | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 085cf2788f9..01edd10b896 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -15,3 +15,51 @@ INSERT INTO t1 VALUES (1), (2); DROP TABLE t1; +CREATE TABLE t1 (a decimal(240, 20)); +INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), +("0987654321098765432109876543210987654321"); +-- MySQL dump 9.09 +-- +-- Host: localhost Database: test +-- ------------------------------------------------------ +-- Server version 4.0.17-debug-log + +-- +-- Table structure for table `t1` +-- + +CREATE TABLE t1 ( + a decimal(240,20) default NULL +) TYPE=MyISAM; + +-- +-- Dumping data for table `t1` +-- + +INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890.00000000000000000000"); +INSERT INTO t1 VALUES ("0987654321098765432109876543210987654321.00000000000000000000"); + +DROP TABLE t1; +CREATE TABLE t1 (a double); +INSERT INTO t1 VALUES (-9e999999); +-- MySQL dump 9.09 +-- +-- Host: localhost Database: test +-- ------------------------------------------------------ +-- Server version 4.0.17-debug-log + +-- +-- Table structure for table `t1` +-- + +CREATE TABLE t1 ( + a double default NULL +) TYPE=MyISAM; + +-- +-- Dumping data for table `t1` +-- + +INSERT INTO t1 VALUES (NULL); + +DROP TABLE t1; From 124c4ca346a46a68febd044f97ad12965643e1b8 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Wed, 10 Dec 2003 22:26:31 +0300 Subject: [PATCH 42/89] cleanup: if there is return from if-part, we don't need else statement --- sql/field.cc | 4 ++-- sql/item.cc | 5 ++--- sql/item_cmpfunc.cc | 5 ++--- sql/item_func.cc | 25 ++++++++++--------------- sql/item_strfunc.cc | 13 +++++-------- sql/item_sum.cc | 6 ++---- sql/mysqld.cc | 2 +- sql/opt_range.cc | 2 +- sql/sql_analyse.cc | 8 ++------ sql/sql_insert.cc | 19 ++++++++----------- sql/sql_parse.cc | 3 +-- 11 files changed, 36 insertions(+), 56 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index 1070d0f7b7d..d43089ec35c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -848,7 +848,7 @@ int Field_decimal::cmp(const char *a_ptr,const char *b_ptr) return 0; if (*a_ptr == '-') return -1; - else if (*b_ptr == '-') + if (*b_ptr == '-') return 1; while (a_ptr != end) @@ -3018,7 +3018,7 @@ void Field_year::store(const char *from, uint len) current_thd->cuted_fields++; return; } - else if (current_thd->count_cuted_fields && !test_if_int(from,len)) + if (current_thd->count_cuted_fields && !test_if_int(from,len)) current_thd->cuted_fields++; if (nr != 0 || len != 4) { diff --git a/sql/item.cc b/sql/item.cc index fc6256d4fed..60fc383d757 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -694,10 +694,9 @@ Item_result item_cmp_type(Item_result a,Item_result b) { if (a == STRING_RESULT && b == STRING_RESULT) return STRING_RESULT; - else if (a == INT_RESULT && b == INT_RESULT) + if (a == INT_RESULT && b == INT_RESULT) return INT_RESULT; - else - return REAL_RESULT; + return REAL_RESULT; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 63f3a8985c5..82f368970e2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -463,10 +463,9 @@ static Item_result item_store_type(Item_result a,Item_result b) { if (a == STRING_RESULT || b == STRING_RESULT) return STRING_RESULT; - else if (a == REAL_RESULT || b == REAL_RESULT) + if (a == REAL_RESULT || b == REAL_RESULT) return REAL_RESULT; - else - return INT_RESULT; + return INT_RESULT; } void diff --git a/sql/item_func.cc b/sql/item_func.cc index 8d7ee637d73..64b1c5d4d8a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -214,8 +214,7 @@ String *Item_real_func::val_str(String *str) double nr=val(); if (null_value) return 0; /* purecov: inspected */ - else - str->set(nr,decimals); + str->set(nr,decimals); return str; } @@ -227,7 +226,7 @@ String *Item_num_func::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; /* purecov: inspected */ - else if (!unsigned_flag) + if (!unsigned_flag) str->set(nr); else str->set((ulonglong) nr); @@ -237,8 +236,7 @@ String *Item_num_func::val_str(String *str) double nr=val(); if (null_value) return 0; /* purecov: inspected */ - else - str->set(nr,decimals); + str->set(nr,decimals); } return str; } @@ -257,7 +255,7 @@ String *Item_int_func::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else if (!unsigned_flag) + if (!unsigned_flag) str->set(nr); else str->set((ulonglong) nr); @@ -286,7 +284,7 @@ String *Item_num_op::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; /* purecov: inspected */ - else if (!unsigned_flag) + if (!unsigned_flag) str->set(nr); else str->set((ulonglong) nr); @@ -296,8 +294,7 @@ String *Item_num_op::val_str(String *str) double nr=val(); if (null_value) return 0; /* purecov: inspected */ - else - str->set(nr,decimals); + str->set(nr,decimals); } return str; } @@ -799,7 +796,7 @@ String *Item_func_min_max::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else if (!unsigned_flag) + if (!unsigned_flag) str->set(nr); else str->set((ulonglong) nr); @@ -810,8 +807,7 @@ String *Item_func_min_max::val_str(String *str) double nr=val(); if (null_value) return 0; /* purecov: inspected */ - else - str->set(nr,decimals); + str->set(nr,decimals); return str; } case STRING_RESULT: @@ -1392,8 +1388,7 @@ String *Item_func_udf_float::val_str(String *str) double nr=val(); if (null_value) return 0; /* purecov: inspected */ - else - str->set(nr,decimals); + str->set(nr,decimals); return str; } @@ -1413,7 +1408,7 @@ String *Item_func_udf_int::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else if (!unsigned_flag) + if (!unsigned_flag) str->set(nr); else str->set((ulonglong) nr); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 40b18755744..7434f6bd57b 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1706,14 +1706,11 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value, str->length(length); return str; } - else - { - if (tmp_value->alloc(length)) - return 0; - (void) tmp_value->copy(*res); - tmp_value->length(length); - return tmp_value; - } + if (tmp_value->alloc(length)) + return 0; + (void) tmp_value->copy(*res); + tmp_value->length(length); + return tmp_value; } res->length(length); return res; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index e18fa83e49d..4121fa65433 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1153,8 +1153,7 @@ String *Item_sum_udf_float::val_str(String *str) double nr=val(); if (null_value) return 0; /* purecov: inspected */ - else - str->set(nr,decimals); + str->set(nr,decimals); return str; } @@ -1172,8 +1171,7 @@ String *Item_sum_udf_int::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else - str->set(nr); + str->set(nr); return str; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 410a1644eec..b75a94a261c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1043,7 +1043,7 @@ static void set_user(const char *user) } return; } - else if (!user) + if (!user) { if (!opt_bootstrap) { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4bbeaca8a79..02b7699fad6 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1474,7 +1474,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) } return 0; } - else if (!key2) + if (!key2) { key1->use_count--; key1->free_tree(); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index d6abe6497df..bd8c0e5ba87 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -220,8 +220,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len) info->is_float = 1; // we can't use variable decimals here return 1; } - else - return 0; + return 0; } for (str++; *(end - 1) == '0'; end--); // jump over zeros at the end if (str == end) // number was something like '123.000' @@ -236,11 +235,8 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len) info->dval = atod(begin); return 1; } - else - return 0; } - else - return 0; + return 0; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3414e76e092..a92379a6d3b 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1409,18 +1409,15 @@ bool select_insert::send_eof() ::send_error(&thd->net); return 1; } + char buff[160]; + if (info.handle_duplicates == DUP_IGNORE) + sprintf(buff,ER(ER_INSERT_INFO),info.records,info.records-info.copied, + thd->cuted_fields); else - { - char buff[160]; - if (info.handle_duplicates == DUP_IGNORE) - sprintf(buff,ER(ER_INSERT_INFO),info.records,info.records-info.copied, - thd->cuted_fields); - else - sprintf(buff,ER(ER_INSERT_INFO),info.records,info.deleted, - thd->cuted_fields); - ::send_ok(&thd->net,info.copied+info.deleted,last_insert_id,buff); - return 0; - } + sprintf(buff,ER(ER_INSERT_INFO),info.records,info.deleted, + thd->cuted_fields); + ::send_ok(&thd->net,info.copied+info.deleted,last_insert_id,buff); + return 0; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index fc9c21586d9..d59dda43d67 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -268,8 +268,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, decrease_user_connections(thd->user_connect); return error; } - else - send_ok(net); // Ready to handle questions + send_ok(net); // Ready to handle questions thd->password= test(passwd[0]); // Remember for error messages return 0; // ok } From 7e92336b1da07c6424f3bdffcc5d3edf268268fa Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 11 Dec 2003 06:24:08 +0200 Subject: [PATCH 43/89] Fixed a possible memory leak on MacOSX when using the shared libmysql.so library (Bug #2061) mysql_server_init() now returns error code if something went wrong (Bug #2062) Don't use my_fopen() when reading symlink information as this may cause problems when a lot of files are opened. Free thread keys with pthread_key_delete() instead of relying on automatic free. (Bug #2062) Fixed bug in UNION statement with alias '*'. (Bug #1249) Fixed a bug in DELETE ... ORDER BY ... LIMIT where the rows where not deleted in the proper order. (Bug #1024). FOUND_ROWS() could return incorrect number of rows after a query with an impossible WHERE condition. HOW DATABASES doesn't anymore show .sym files (on windows) that doesn't point to a valid directory. (Bug #1385) --- include/config-win.h | 4 ++++ include/my_pthread.h | 3 +++ include/my_sys.h | 2 +- include/mysql.h | 2 +- include/mysql_com.h | 2 +- libmysql/libmysql.c | 22 ++++++++++++++++------ mysql-test/r/limit.result | 23 ++++++++++++++++++++--- mysql-test/r/select_found.result | 19 +++++++++++++++++++ mysql-test/r/union.result | 6 +++++- mysql-test/t/limit.test | 22 +++++++++++++++++++--- mysql-test/t/select_found.test | 14 ++++++++++++++ mysql-test/t/union.test | 9 ++++++++- mysys/mf_pack.c | 27 ++++++++++++++------------- mysys/my_init.c | 20 +++++++++++++++----- mysys/my_lib.c | 6 ++++-- mysys/my_thr_init.c | 26 ++++++++++++++++++++------ sql/sql_base.cc | 7 ++++++- sql/sql_delete.cc | 12 +++++++++--- sql/sql_select.cc | 2 ++ sql/sql_show.cc | 12 ++++++++++++ sql/sql_yacc.yy | 1 + 21 files changed, 194 insertions(+), 47 deletions(-) diff --git a/include/config-win.h b/include/config-win.h index b30f50f0edb..e6f03a10afb 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -151,6 +151,10 @@ typedef uint rf_SetTimer; #define USE_MB_IDENT 1 #define USE_STRCOLL 1 +/* All windows servers should support .sym files */ +#undef USE_SYMDIR +#define USE_SYMDIR + /* If LOAD DATA LOCAL INFILE should be enabled by default */ #define ENABLED_LOCAL_INFILE 1 diff --git a/include/my_pthread.h b/include/my_pthread.h index 16a14ac5038..59367ee903c 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -115,6 +115,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/ #undef SAFE_MUTEX /* This will cause conflicts */ #define pthread_key(T,V) DWORD V #define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF) +#define pthread_key_delete(A) TlsFree(A) #define pthread_getspecific(A) (TlsGetValue(A)) #define my_pthread_getspecific(T,A) ((T) TlsGetValue(A)) #define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V)) @@ -123,6 +124,7 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/ #else #define pthread_key(T,V) __declspec(thread) T V #define pthread_key_create(A,B) pthread_dummy(0) +#define pthread_key_delete(A) pthread_dummy(0) #define pthread_getspecific(A) (&(A)) #define my_pthread_getspecific(T,A) (&(A)) #define my_pthread_getspecific_ptr(T,V) (V) @@ -178,6 +180,7 @@ extern int pthread_mutex_destroy (pthread_mutex_t *); typedef int pthread_attr_t; /* Needed by Unixware 7.0.0 */ #define pthread_key_create(A,B) thr_keycreate((A),(B)) +#define pthread_key_delete(A) thr_keydelete(A) #define pthread_handler_decl(A,B) void *A(void *B) #define pthread_key(T,V) pthread_key_t V diff --git a/include/my_sys.h b/include/my_sys.h index df8b9759e5d..acb4c01b4f1 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -577,7 +577,7 @@ extern int my_snprintf(char* to, size_t n, const char* fmt, ...); extern int my_message(uint my_err, const char *str,myf MyFlags); extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags); extern int my_message_curses(uint my_err, const char *str,myf MyFlags); -extern void my_init(void); +extern my_bool my_init(void); extern void my_end(int infoflag); extern int my_redel(const char *from, const char *to, int MyFlags); extern int my_copystat(const char *from, const char *to, int MyFlags); diff --git a/include/mysql.h b/include/mysql.h index 0c91266e19c..3ffc014c449 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -426,7 +426,7 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); int simple_command(MYSQL *mysql,enum enum_server_command command, const char *arg, unsigned long length, my_bool skipp_check); unsigned long net_safe_read(MYSQL* mysql); -void mysql_once_init(void); +int mysql_once_init(void); extern my_bool server_inited; diff --git a/include/mysql_com.h b/include/mysql_com.h index a874034ba46..e183a0ed423 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -241,7 +241,7 @@ void hash_password(unsigned long *result, const char *password); /* Some other useful functions */ -void my_init(void); +my_bool my_init(void); int load_defaults(const char *conf_file, const char **groups, int *argc, char ***argv); my_bool my_thread_init(void); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 5fcc3ba5ee0..607d8af6e50 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -102,8 +102,7 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)), char **argv __attribute__((unused)), char **groups __attribute__((unused))) { - mysql_once_init(); - return 0; + return (int) mysql_once_init(); } void STDCALL mysql_server_end() @@ -1436,7 +1435,8 @@ STDCALL mysql_rpl_query_type(const char* q, int len) MYSQL * STDCALL mysql_init(MYSQL *mysql) { - mysql_once_init(); + if (mysql_once_init()) + return 0; if (!mysql) { if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL)))) @@ -1476,15 +1476,20 @@ mysql_init(MYSQL *mysql) This function is called by mysql_init() and indirectly called by mysql_query(), so one should never have to call this from an outside program. + + RETURN + 0 ok + 1 could not initialize environment (out of memory or thread keys) */ -void mysql_once_init(void) +int mysql_once_init(void) { if (!mysql_client_init) { mysql_client_init=1; org_my_init_done=my_init_done; - my_init(); /* Will init threads */ + if (my_init()) /* Will init threads */ + return 1; init_client_errs(); if (!mysql_port) { @@ -1518,10 +1523,15 @@ void mysql_once_init(void) } #ifdef THREAD else - my_thread_init(); /* Init if new thread */ + { + if (my_thread_init()) /* Init if new thread */ + return 1; + } #endif + return 0; } + /************************************************************************** Fill in SSL part of MYSQL structure and set 'use_ssl' flag. NB! Errors are not reported until you do mysql_real_connect. diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result index 5a8edc99c12..c82105e6a49 100644 --- a/mysql-test/r/limit.result +++ b/mysql-test/r/limit.result @@ -36,9 +36,7 @@ a b 3 4 drop table t1; create table t1 (i int); -insert into t1 (i) values(1); -insert into t1 (i) values(1); -insert into t1 (i) values(1); +insert into t1 (i) values(1),(1),(1); delete from t1 limit 1; update t1 set i=2 limit 1; delete from t1 limit 0; @@ -50,3 +48,22 @@ i drop table t1; select 0 limit 0; 0 +CREATE TABLE t1(id int auto_increment primary key, id2 int, index(id2)); +INSERT INTO t1 (id2) values (0),(0),(0); +DELETE FROM t1 WHERE id=1; +INSERT INTO t1 SET id2=0; +SELECT * FROM t1; +id id2 +4 0 +2 0 +3 0 +DELETE FROM t1 WHERE id2 = 0 ORDER BY id LIMIT 1; +SELECT * FROM t1; +id id2 +4 0 +3 0 +DELETE FROM t1 WHERE id2 = 0 ORDER BY id desc LIMIT 1; +SELECT * FROM t1; +id id2 +3 0 +DROP TABLE t1; diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result index 0a7f464cf7b..419ffb73d59 100644 --- a/mysql-test/r/select_found.result +++ b/mysql-test/r/select_found.result @@ -169,3 +169,22 @@ SELECT FOUND_ROWS(); FOUND_ROWS() 2 drop table t1; +create table t1 (id int, primary key (id)); +insert into t1 values (1), (2), (3), (4), (5); +select SQL_CALC_FOUND_ROWS * from t1 where id > 3 limit 0, 1; +id +4 +select FOUND_ROWS(); +FOUND_ROWS() +2 +select SQL_CALC_FOUND_ROWS * from t1 where id > 3 AND 1=2 limit 0, 1; +id +select FOUND_ROWS(); +FOUND_ROWS() +0 +select SQL_CALC_FOUND_ROWS * from t1 where id > 6 limit 0, 1; +id +select FOUND_ROWS(); +FOUND_ROWS() +0 +drop table t1; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index cd5d600edf4..fc5aa1ad0cb 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -3,7 +3,7 @@ CREATE TABLE t1 (a int not null, b char (10) not null); insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); CREATE TABLE t2 (a int not null, b char (10) not null); insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e'); -select a,b from t1 union select a,b from t2; +select a,b from t1 union distinct select a,b from t2; a b 1 a 2 b @@ -423,3 +423,7 @@ create temporary table t1 select a from t1 union select a from t2; create table t1 select a from t1 union select a from t2; INSERT TABLE 't1' isn't allowed in FROM table list drop table t1,t2; +select length(version()) > 1 as `*` UNION select 2; +* +1 +2 diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test index d4f6ce186cf..32962073eee 100644 --- a/mysql-test/t/limit.test +++ b/mysql-test/t/limit.test @@ -19,9 +19,7 @@ select * from t1; drop table t1; create table t1 (i int); -insert into t1 (i) values(1); -insert into t1 (i) values(1); -insert into t1 (i) values(1); +insert into t1 (i) values(1),(1),(1); delete from t1 limit 1; update t1 set i=2 limit 1; delete from t1 limit 0; @@ -29,4 +27,22 @@ update t1 set i=3 limit 0; select * from t1; drop table t1; +# LIMIT 0 + select 0 limit 0; + +# +# Test with DELETE, ORDER BY and limit (bug #1024) +# + +CREATE TABLE t1(id int auto_increment primary key, id2 int, index(id2)); +INSERT INTO t1 (id2) values (0),(0),(0); +DELETE FROM t1 WHERE id=1; +INSERT INTO t1 SET id2=0; +SELECT * FROM t1; +DELETE FROM t1 WHERE id2 = 0 ORDER BY id LIMIT 1; +# should have deleted WHERE id=2 +SELECT * FROM t1; +DELETE FROM t1 WHERE id2 = 0 ORDER BY id desc LIMIT 1; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test index 0a483c860cb..f5ee4d5c010 100644 --- a/mysql-test/t/select_found.test +++ b/mysql-test/t/select_found.test @@ -85,3 +85,17 @@ INSERT INTO t1 (titre,maxnumrep) VALUES SELECT SQL_CALC_FOUND_ROWS titre,numeropost,maxnumrep FROM t1 WHERE numeropost IN (1,2) ORDER BY maxnumrep DESC LIMIT 0, 1; SELECT FOUND_ROWS(); drop table t1; + +# +# Test problem with impossible WHERE (Bug #1468) +# + +create table t1 (id int, primary key (id)); +insert into t1 values (1), (2), (3), (4), (5); +select SQL_CALC_FOUND_ROWS * from t1 where id > 3 limit 0, 1; +select FOUND_ROWS(); +select SQL_CALC_FOUND_ROWS * from t1 where id > 3 AND 1=2 limit 0, 1; +select FOUND_ROWS(); +select SQL_CALC_FOUND_ROWS * from t1 where id > 6 limit 0, 1; +select FOUND_ROWS(); +drop table t1; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index ba4673e9a88..badfe4b9a3a 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -8,7 +8,7 @@ insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); CREATE TABLE t2 (a int not null, b char (10) not null); insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e'); -select a,b from t1 union select a,b from t2; +select a,b from t1 union distinct select a,b from t2; select a,b from t1 union all select a,b from t2; select a,b from t1 union all select a,b from t2 order by b; select a,b from t1 union all select a,b from t2 union select 7,'g'; @@ -227,3 +227,10 @@ create temporary table t1 select a from t1 union select a from t2; --error 1093 create table t1 select a from t1 union select a from t2; drop table t1,t2; + +# +# Problem with alias '*' (BUG #1249) +# + +select length(version()) > 1 as `*` UNION select 2; + diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index b3aa347006e..e2e811fe89a 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -210,13 +210,13 @@ uint cleanup_dirname(register my_string to, const char *from) } /* cleanup_dirname */ - /* - On system where you don't have symbolic links, the following - code will allow you to create a file: - directory-name.lnk that should contain the real path - to the directory. This will be used if the directory name - doesn't exists - */ +/* + On system where you don't have symbolic links, the following + code will allow you to create a file: + directory-name.sym that should contain the real path + to the directory. This will be used if the directory name + doesn't exists +*/ my_bool my_use_symdir=0; /* Set this if you want to use symdirs */ @@ -228,16 +228,17 @@ void symdirget(char *dir) char *pos=strend(dir); if (dir[0] && pos[-1] != FN_DEVCHAR && access(dir, F_OK)) { - FILE *fp; + File file; + uint length; char temp= *(--pos); /* May be "/" or "\" */ strmov(pos,".sym"); - fp = my_fopen(dir, O_RDONLY,MYF(0)); + file= my_open(dir, O_RDONLY, MYF(0)); *pos++=temp; *pos=0; /* Restore old filename */ - if (fp) + if (file >= 0) { - if (fgets(buff, sizeof(buff)-1, fp)) + if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0) { - for (pos=strend(buff); + for (pos= buff + length ; pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ; pos --); @@ -247,7 +248,7 @@ void symdirget(char *dir) strmake(dir,buff, (uint) (pos-buff)); } - my_fclose(fp,MYF(0)); + my_close(file, MYF(0)); } } } diff --git a/mysys/my_init.c b/mysys/my_init.c index a8a184a2cb4..8d4ba2c97b6 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -62,13 +62,22 @@ static ulong atoi_octal(const char *str) } - /* Init my_sys functions and my_sys variabels */ +/* + Init my_sys functions and my_sys variabels -void my_init(void) + SYNOPSIS + my_init() + + RETURN + 0 ok + 1 Couldn't initialize environment +*/ + +my_bool my_init(void) { my_string str; if (my_init_done) - return; + return 0; my_init_done=1; #if defined(THREAD) && defined(SAFE_MUTEX) safe_mutex_global_init(); /* Must be called early */ @@ -78,7 +87,8 @@ void my_init(void) #if defined(HAVE_PTHREAD_INIT) pthread_init(); /* Must be called before DBUG_ENTER */ #endif - my_thread_global_init(); + if (my_thread_global_init()) + return 1; #if !defined( __WIN__) && !defined(OS2) && !defined(__NETWARE__) sigfillset(&my_signals); /* signals blocked by mf_brkhant */ #endif @@ -110,7 +120,7 @@ void my_init(void) #ifdef __WIN__ win32_init_tcp_ip(); #endif - DBUG_VOID_RETURN; + DBUG_RETURN(0); } } /* my_init */ diff --git a/mysys/my_lib.c b/mysys/my_lib.c index 035bafd07b9..426acedc646 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -602,9 +602,11 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags) if ((m_used= (stat_area == NULL))) if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags))) goto error; - if ( ! stat((my_string) path, (struct stat *) stat_area) ) + if (! stat((my_string) path, (struct stat *) stat_area) ) DBUG_RETURN(stat_area); - my_errno=errno; + + DBUG_PRINT("error",("Got errno: %d from stat", errno)); + my_errno= errno; if (m_used) /* Free if new area */ my_free((gptr) stat_area,MYF(0)); diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 9f64e9dcb60..3827b24ac32 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -44,12 +44,23 @@ pthread_mutexattr_t my_fast_mutexattr; pthread_mutexattr_t my_errchk_mutexattr; #endif +/* + initialize thread environment + + SYNOPSIS + my_thread_global_init() + + RETURN + 0 ok + 1 error (Couldn't create THR_KEY_mysys) +*/ + my_bool my_thread_global_init(void) { - if (pthread_key_create(&THR_KEY_mysys,free)) + if (pthread_key_create(&THR_KEY_mysys,0)) { fprintf(stderr,"Can't initialize threads: error %d\n",errno); - exit(1); + return 1; } #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP pthread_mutexattr_init(&my_fast_mutexattr); @@ -79,15 +90,18 @@ my_bool my_thread_global_init(void) #ifndef HAVE_GETHOSTBYNAME_R pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW); #endif - return my_thread_init(); + if (my_thread_init()) + { + my_thread_global_end(); /* Clean up */ + return 1; + } + return 0; } void my_thread_global_end(void) { -#if defined(USE_TLS) - (void) TlsFree(THR_KEY_mysys); -#endif + pthread_key_delete(THR_KEY_mysys); #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP pthread_mutexattr_destroy(&my_fast_mutexattr); #endif diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e4694adb9a2..dd80062d6e7 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1868,8 +1868,13 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List &fields, while ((item=it++)) { + /* + Expand * to all fields if this is not the temporary table for an + a UNION result + */ if (item->type() == Item::FIELD_ITEM && - ((Item_field*) item)->field_name[0] == '*') + ((Item_field*) item)->field_name[0] == '*' && + !((Item_field*) item)->field) { uint elem=fields.elements; if (insert_fields(thd,tables,((Item_field*) item)->db_name, diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 34a79ecd78d..ee2b720907d 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -78,7 +78,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, DBUG_RETURN(-1); if ((select && select->check_quick(thd, test(thd->options & OPTION_SAFE_UPDATES), - limit)) || + limit)) || !limit) { delete select; @@ -117,13 +117,19 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, if (setup_order(thd, &tables, fields, all_fields, order) || !(sortorder=make_unireg_sortorder(order, &length)) || (table->found_records = filesort(table, sortorder, length, - (SQL_SELECT *) 0, 0L, HA_POS_ERROR, + select, 0L, HA_POS_ERROR, &examined_rows)) == HA_POS_ERROR) { delete select; - DBUG_RETURN(-1); // This will force out message + DBUG_RETURN(-1); // This will force out message } + /* + Filesort has already found and selected the rows we want to delete, + so we don't need the where clause + */ + delete select; + select= 0; } init_read_record(&info,thd,table,select,1,1); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index df4b0226ff6..892ad02bb5b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3273,6 +3273,8 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables, } result->send_eof(); // Should be safe } + /* Update results for FOUND_ROWS */ + join->thd->limit_found_rows= join->thd->examined_row_count= 0; DBUG_RETURN(0); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a7de04d0bfa..cb6cd18b7c8 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -197,7 +197,19 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, #ifdef USE_SYMDIR char *ext; if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym")) + { + /* Only show the sym file if it points to a directory */ + char buff[FN_REFLEN], *end; + MY_STAT status; *ext=0; /* Remove extension */ + unpack_dirname(buff, file->name); + end= strend(buff); + if (end != buff && end[-1] == FN_LIBCHAR) + end[-1]= 0; // Remove end FN_LIBCHAR + if (!my_stat(buff, &status, MYF(0)) || + !MY_S_ISDIR(status.st_mode)) + continue; + } else #endif { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 03837300904..b5b9a4cdfb7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4014,5 +4014,6 @@ optional_order_or_limit: union_option: /* empty */ {} + | DISTINCT {} | ALL { Lex->union_option=1; } ; From 9698e236ab1b589cbfb2c4e8bc51b58bdfaffe02 Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Thu, 11 Dec 2003 13:50:47 +0400 Subject: [PATCH 44/89] Disable some tests until replace can handle regexp --- mysql-test/r/mysqldump.result | 48 ----------------------------------- mysql-test/t/mysqldump.test | 20 ++++++++------- 2 files changed, 11 insertions(+), 57 deletions(-) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 01edd10b896..085cf2788f9 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -15,51 +15,3 @@ INSERT INTO t1 VALUES (1), (2); DROP TABLE t1; -CREATE TABLE t1 (a decimal(240, 20)); -INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), -("0987654321098765432109876543210987654321"); --- MySQL dump 9.09 --- --- Host: localhost Database: test --- ------------------------------------------------------ --- Server version 4.0.17-debug-log - --- --- Table structure for table `t1` --- - -CREATE TABLE t1 ( - a decimal(240,20) default NULL -) TYPE=MyISAM; - --- --- Dumping data for table `t1` --- - -INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890.00000000000000000000"); -INSERT INTO t1 VALUES ("0987654321098765432109876543210987654321.00000000000000000000"); - -DROP TABLE t1; -CREATE TABLE t1 (a double); -INSERT INTO t1 VALUES (-9e999999); --- MySQL dump 9.09 --- --- Host: localhost Database: test --- ------------------------------------------------------ --- Server version 4.0.17-debug-log - --- --- Table structure for table `t1` --- - -CREATE TABLE t1 ( - a double default NULL -) TYPE=MyISAM; - --- --- Dumping data for table `t1` --- - -INSERT INTO t1 VALUES (NULL); - -DROP TABLE t1; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 87363855db0..aea5859fcfa 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -11,19 +11,21 @@ DROP TABLE t1; # # Bug #2005 +# TODO: solve the problem with 'replace' and enable test # -CREATE TABLE t1 (a decimal(240, 20)); -INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), -("0987654321098765432109876543210987654321"); ---exec $MYSQL_DUMP test t1 -DROP TABLE t1; +#CREATE TABLE t1 (a decimal(240, 20)); +#INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), +#("0987654321098765432109876543210987654321"); +#--exec $MYSQL_DUMP test t1 +#DROP TABLE t1; # # Bug #2055 +# TODO: solve the problem with 'replace' and enable test # -CREATE TABLE t1 (a double); -INSERT INTO t1 VALUES (-9e999999); ---exec $MYSQL_DUMP test t1 -DROP TABLE t1; +#CREATE TABLE t1 (a double); +#INSERT INTO t1 VALUES (-9e999999); +#--exec $MYSQL_DUMP -X test t1 +#DROP TABLE t1; From 23eef56f2372cde9f95396a932ecd5e24fc55769 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Thu, 11 Dec 2003 10:53:28 +0100 Subject: [PATCH 45/89] - Rather "bk cat" the files from the mysqldoc BK tree during Bootstrap than trying to copy them (they might have been "bk clean"ed and thus not available for copying) - Brushed up the Bootstrap online help a bit --- Build-tools/Bootstrap | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index 94446d9880f..c1a416356f1 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -274,11 +274,14 @@ if (defined $opt_changelog) # unless ($opt_skip_manual) { - $msg= "Adding manual.texi"; + $msg= "Updating manual files"; &logger($msg); - $command= "install -m 644 $opt_docdir/Docs/{manual,reservedwords}.texi"; - $command.= " $target_dir/Docs/"; - &run_command($command, "Could not update the manual in $target_dir/Docs/!"); + foreach $file qw/internals manual reservedwords/ + { + $command= "bk cat $opt_docdir/Docs/$file.texi"; + $command.= "> $target_dir/Docs/$file.texi"; + &run_command($command, "Could not updated $file.texi in $target_dir/Docs/!"); + } } # @@ -364,11 +367,13 @@ sub print_help Usage: Bootstrap [options] -Checks out (exports) a clear-text version of the given local BitKeeper +Creates a MySQL source distribution to be used for the release builds. + +It checks out (exports) a clear-text version of the given local BitKeeper repository, creates and adds a Changelog file (if requested), adds the -latest manual.texi from the mysqldoc tree and builds a source distribution -(*.tar.gz) file. Optionally, the test suite can be run before the source -archive is being created. +latest manual files from the mysqldoc BK tree and builds a source +distribution (*.tar.gz) file. Optionally, the test suite and the +distribution check can be run before the source archive is being created. Options: From 0395a3dd4655c9e68991dbfd27483ca817526e2b Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Thu, 11 Dec 2003 17:37:45 +0400 Subject: [PATCH 46/89] Added --comments mysqldump option (default value is 1). Fixed mysqldump test. --- client/mysqldump.c | 23 ++++++++++++++--------- mysql-test/r/mysqldump.result | 20 ++++++++++++++++++++ mysql-test/t/mysqldump.test | 22 ++++++++++------------ 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 7092503fa25..b7a61845f7c 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -78,7 +78,7 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0, opt_alldbs=0,opt_create_db=0,opt_first_slave=0, opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0, opt_delete_master_logs=0, tty_password=0, - opt_single_transaction=0; + opt_single_transaction=0, opt_comments= 0; static MYSQL mysql_connection,*sock=0; static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, @@ -242,6 +242,9 @@ static struct my_option my_long_options[] = (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L, MALLOC_OVERHEAD-1024, 1024, 0}, + {"comments", 'i', "Write additional information.", + (gptr*) &opt_comments, (gptr*) &opt_comments, 0, GET_BOOL, NO_ARG, + 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -302,7 +305,7 @@ static void write_header(FILE *sql_file, char *db_name) fprintf(sql_file,"\n"); fprintf(sql_file,"\n"); } - else + else if (opt_comments) { fprintf(sql_file, "-- MySQL dump %s\n--\n", DUMP_VERSION); fprintf(sql_file, "-- Host: %s Database: %s\n", @@ -620,7 +623,7 @@ static uint getTableStructure(char *table, char* db) } write_header(sql_file, db); } - if (!opt_xml) + if (!opt_xml && opt_comments) fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n", result_table); if (opt_drop) @@ -698,7 +701,7 @@ static uint getTableStructure(char *table, char* db) } write_header(sql_file, db); } - if (!opt_xml) + if (!opt_xml && opt_comments) fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n", result_table); if (opt_drop) @@ -964,14 +967,14 @@ static void dumpTable(uint numFields, char *table) } else { - if (!opt_xml) + if (!opt_xml && opt_comments) fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n", result_table); sprintf(query, "SELECT /*!40001 SQL_NO_CACHE */ * FROM %s", result_table); if (where) { - if (!opt_xml) + if (!opt_xml && opt_comments) fprintf(md_result_file,"-- WHERE: %s\n",where); strxmov(strend(query), " WHERE ",where,NullS); } @@ -1298,7 +1301,8 @@ static int init_dumping(char *database) /* length of table name * 2 (if name contain quotas), 2 quotas and 0 */ char quoted_database_buf[64*2+3]; char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted); - fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", database); + if (opt_comments) + fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", database); if (!opt_create_db) fprintf(md_result_file,"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n", qdatabase); @@ -1499,8 +1503,9 @@ int main(int argc, char **argv) row = mysql_fetch_row(master); if (row && row[0] && row[1]) { - fprintf(md_result_file, - "\n--\n-- Position to start replication from\n--\n\n"); + if (opt_comments) + fprintf(md_result_file, + "\n--\n-- Position to start replication from\n--\n\n"); fprintf(md_result_file, "CHANGE MASTER TO MASTER_LOG_FILE='%s', \ MASTER_LOG_POS=%s ;\n",row[0],row[1]); diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 085cf2788f9..27ca3fbaaf5 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -15,3 +15,23 @@ INSERT INTO t1 VALUES (1), (2); DROP TABLE t1; +CREATE TABLE t1 (a decimal(240, 20)); +INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), +("0987654321098765432109876543210987654321"); +CREATE TABLE t1 ( + a decimal(240,20) default NULL +) TYPE=MyISAM; + +INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890.00000000000000000000"); +INSERT INTO t1 VALUES ("0987654321098765432109876543210987654321.00000000000000000000"); + +DROP TABLE t1; +CREATE TABLE t1 (a double); +INSERT INTO t1 VALUES (-9e999999); +CREATE TABLE t1 ( + a double default NULL +) TYPE=MyISAM; + +INSERT INTO t1 VALUES (NULL); + +DROP TABLE t1; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index aea5859fcfa..525949bd602 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -6,26 +6,24 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); ---exec $MYSQL_DUMP -X test t1 +--exec $MYSQL_DUMP --skip-comments -X test t1 DROP TABLE t1; # # Bug #2005 -# TODO: solve the problem with 'replace' and enable test # -#CREATE TABLE t1 (a decimal(240, 20)); -#INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), -#("0987654321098765432109876543210987654321"); -#--exec $MYSQL_DUMP test t1 -#DROP TABLE t1; +CREATE TABLE t1 (a decimal(240, 20)); +INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), +("0987654321098765432109876543210987654321"); +--exec $MYSQL_DUMP --skip-comments test t1 +DROP TABLE t1; # # Bug #2055 -# TODO: solve the problem with 'replace' and enable test # -#CREATE TABLE t1 (a double); -#INSERT INTO t1 VALUES (-9e999999); -#--exec $MYSQL_DUMP -X test t1 -#DROP TABLE t1; +CREATE TABLE t1 (a double); +INSERT INTO t1 VALUES (-9e999999); +--exec $MYSQL_DUMP --skip-comments test t1 +DROP TABLE t1; From fddab846d4f3658b3488cbec43c7d16f07f14594 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Thu, 11 Dec 2003 16:47:50 +0100 Subject: [PATCH 47/89] chk_del() should not check key delete-chain make a test for -inf more portable (-Inf) --- client/mysqldump.c | 6 +++--- myisam/mi_check.c | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index b7a61845f7c..d8e63cd611a 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -179,7 +179,7 @@ static struct my_option my_long_options[] = {"single-transaction", OPT_TRANSACTION, "Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables.", (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, + 0, 0, 0, 0, 0, 0}, {"no-create-db", 'n', "'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}", (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0, @@ -1072,7 +1072,7 @@ static void dumpTable(uint numFields, char *table) { /* change any strings ("inf", "-inf", "nan") into NULL */ char *ptr = row[i]; - if (isalpha(*ptr) || (*ptr == '-' && *(ptr+1) == 'i')) + if (isalpha(*ptr) || (*ptr == '-' && isalpha(ptr[1]))) dynstr_append(&extended_row, "NULL"); else { @@ -1118,7 +1118,7 @@ static void dumpTable(uint numFields, char *table) if (opt_xml) fprintf(md_result_file, "\t\t%s\n", field->name,!isalpha(*ptr) ?ptr: "NULL"); - else if (isalpha(*ptr) || (*ptr == '-' && *(ptr+1) == 'i')) + else if (isalpha(*ptr) || (*ptr == '-' && isalpha(ptr[1]))) fputs("NULL", md_result_file); else { diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 7108fdcba9e..007ae950990 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -131,15 +131,8 @@ int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag) char buff[22],buff2[22]; DBUG_ENTER("chk_del"); - if (!(test_flag & T_SILENT)) - puts("- check key delete-chain"); - LINT_INIT(old_link); param->record_checksum=0; - param->key_file_blocks=info->s->base.keystart; - for (j=0 ; j < info->s->state.header.max_block_size ; j++) - if (check_k_link(param,info,j)) - goto wrong; delete_link_length=((info->s->options & HA_OPTION_PACK_RECORD) ? 20 : info->s->rec_reflength+1); @@ -362,6 +355,18 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) char buff[22],buff2[22]; DBUG_ENTER("chk_key"); + if (!(param->testflag & T_SILENT)) + puts("- check key delete-chain"); + + param->key_file_blocks=info->s->base.keystart; + for (key=0 ; key < info->s->state.header.max_block_size ; key++) + if (check_k_link(param,info,key)) + { + if (param->testflag & T_VERBOSE) puts(""); + mi_check_print_error(param,"key delete-link-chain corrupted"); + DBUG_RETURN(-1); + } + if (!(param->testflag & T_SILENT)) puts("- check index reference"); all_keydata=all_totaldata=key_totlength=0; From 54628879fcf511954669d1ee532f639f1f98db47 Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Thu, 11 Dec 2003 14:55:48 -0800 Subject: [PATCH 48/89] Many files: Fixed a bug causing a crash for multi-update/multi-delete with impossible where (bug #1860). --- BitKeeper/etc/logging_ok | 1 + mysql-test/r/multi_update.result | 23 +++++++++++++++++++++++ mysql-test/t/multi_update.test | 26 ++++++++++++++++++++++++++ sql/sql_class.h | 3 +++ sql/sql_delete.cc | 6 +++++- sql/sql_update.cc | 8 ++++++-- 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 17af13c2e75..386ab8a0e49 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -34,6 +34,7 @@ hf@deer.(none) hf@deer.mysql.r18.ru hf@genie.(none) igor@hundin.mysql.fi +igor@rurik.mysql.com jani@dsl-jkl1657.dial.inet.fi jani@hynda.(none) jani@hynda.mysql.fi diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 350cea420b6..5b265d578cd 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -327,3 +327,26 @@ select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and a b a b 2 2 NULL NULL drop table t1,t2; +drop table if exists t1, t2; +create table t1(id1 smallint(5), field char(5)); +create table t2(id2 smallint(5), field char(5)); +insert into t1 values (1, 'a'), (2, 'aa'); +insert into t2 values (1, 'b'), (2, 'bb'); +select * from t1; +id1 field +1 a +2 aa +select * from t2; +id2 field +1 b +2 bb +update t2 inner join t1 on t1.id1=t2.id2 +set t2.field=t1.field +where 0=1; +update t2, t1 set t2.field=t1.field +where t1.id1=t2.id2 and 0=1; +delete t1, t2 from t2 inner join t1 on t1.id1=t2.id2 +where 0=1; +delete t1, t2 from t2,t1 +where t1.id1=t2.id2 and 0=1; +drop table t1,t2; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 7aa4e74cec0..61a284a7aec 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -267,3 +267,29 @@ insert into t2 values (1,1), (3,1); update t1 left join t2 on t1.a=t2.a set t1.b=2, t2.b=2 where t1.b=1 and t2.b=1 or t2.a is NULL; select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and t2.b=1 or t2.a is NULL; drop table t1,t2; + +# Test multi-update and multi-delete with impossible where + +drop table if exists t1, t2; +create table t1(id1 smallint(5), field char(5)); +create table t2(id2 smallint(5), field char(5)); + +insert into t1 values (1, 'a'), (2, 'aa'); +insert into t2 values (1, 'b'), (2, 'bb'); + +select * from t1; +select * from t2; + +update t2 inner join t1 on t1.id1=t2.id2 + set t2.field=t1.field + where 0=1; +update t2, t1 set t2.field=t1.field + where t1.id1=t2.id2 and 0=1; + +delete t1, t2 from t2 inner join t1 on t1.id1=t2.id2 + where 0=1; +delete t1, t2 from t2,t1 + where t1.id1=t2.id2 and 0=1; + +drop table t1,t2; + diff --git a/sql/sql_class.h b/sql/sql_class.h index 9287a0c8c79..c487e212e24 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -848,6 +848,8 @@ class multi_delete : public select_result uint num_of_tables; int error; bool do_delete, transactional_tables, log_delayed, normal_tables; + bool tempfiles_inited; + public: multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables); ~multi_delete(); @@ -874,6 +876,7 @@ class multi_update : public select_result Copy_field *copy_field; enum enum_duplicates handle_duplicates; bool do_update, trans_safe, transactional_tables, log_delayed; + bool tmp_tables_inited; public: multi_update(THD *thd_arg, TABLE_LIST *ut, List *fields, diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index ee2b720907d..399f237bf2f 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -236,7 +236,8 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, uint num_of_tables_arg) : delete_tables(dt), thd(thd_arg), deleted(0), num_of_tables(num_of_tables_arg), error(0), - do_delete(0), transactional_tables(0), log_delayed(0), normal_tables(0) + do_delete(0), transactional_tables(0), log_delayed(0), normal_tables(0), + tempfiles_inited(0) { tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1)); } @@ -297,6 +298,7 @@ multi_delete::initialize_tables(JOIN *join) table->file->ref_length, MEM_STRIP_BUF_SIZE); } + tempfiles_inited= 1; init_ftfuncs(thd,1); DBUG_RETURN(thd->fatal_error != 0); } @@ -422,6 +424,8 @@ int multi_delete::do_deletes(bool from_send_error) table_being_deleted = delete_tables; do_delete= 0; + if (!tempfiles_inited) + DBUG_RETURN(0); for (table_being_deleted=table_being_deleted->next; table_being_deleted ; table_being_deleted=table_being_deleted->next, counter++) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d5034644830..19df0661db3 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -440,7 +440,7 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, :all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0), updated(0), found(0), fields(field_list), values(value_list), table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg), - do_update(1), trans_safe(0) + do_update(1), trans_safe(0), tmp_tables_inited(0) {} @@ -622,6 +622,7 @@ multi_update::initialize_tables(JOIN *join) DBUG_RETURN(1); tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE); } + tmp_tables_inited= 1; DBUG_RETURN(0); } @@ -819,8 +820,11 @@ int multi_update::do_updates(bool from_send_error) ha_rows org_updated; TABLE *table; DBUG_ENTER("do_updates"); + - do_update= 0; // Don't retry this function + do_update= 0; // Don't retry this function + if (!tmp_tables_inited) + DBUG_RETURN(0); for (cur_table= update_tables; cur_table ; cur_table= cur_table->next) { table = cur_table->table; From d7ebfbab1c867e15d2a4dc93eb2ccd9316f57abd Mon Sep 17 00:00:00 2001 From: "dlenev@mysql.com" <> Date: Fri, 12 Dec 2003 03:39:29 +0300 Subject: [PATCH 49/89] Fix for Bug #1952 "SHOW TABLE STATUS very slow w/large number of tables" Replaced old algorithm which were used in my_dir() and stored all information about directory entries in one chunk of memory with new one which stores file names and MY_STAT structures in separate memroot, so now we don't need to copy this data during reallocation of dir_entry array. --- include/my_dir.h | 11 +- mysys/my_lib.c | 343 +++++++++++++++++++++++++---------------------- sql/sql_show.cc | 2 +- 3 files changed, 190 insertions(+), 166 deletions(-) diff --git a/include/my_dir.h b/include/my_dir.h index 4ccda050914..851b6d8d7e9 100644 --- a/include/my_dir.h +++ b/include/my_dir.h @@ -74,14 +74,21 @@ typedef struct my_stat #endif /* USE_MY_STAT_STRUCT */ -typedef struct fileinfo /* Struct returned from my_dir & my_stat */ +/* Struct describing one file returned from my_dir */ +typedef struct fileinfo { char *name; - MY_STAT mystat; + MY_STAT *mystat; } FILEINFO; typedef struct st_my_dir /* Struct returned from my_dir */ { + /* + These members are just copies of parts of DYNAMIC_ARRAY structure, + which is allocated right after the end of MY_DIR structure (MEM_ROOT + for storing names is also resides there). We've left them here because + we don't want to change code that uses my_dir. + */ struct fileinfo *dir_entry; uint number_off_files; } MY_DIR; diff --git a/mysys/my_lib.c b/mysys/my_lib.c index 426acedc646..055e00d2efc 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -62,8 +62,15 @@ #define READDIR(A,B,C) (!(C=readdir(A))) #endif +/* + We are assuming that directory we are reading is either has less than + 100 files and so can be read in one initial chunk or has more than 1000 + files and so big increment are suitable. +*/ +#define ENTRIES_START_SIZE (8192/sizeof(FILEINFO)) +#define ENTRIES_INCREMENT (65536/sizeof(FILEINFO)) +#define NAMES_START_SIZE 32768 -#define STARTSIZE ONCE_ALLOC_INIT*8 /* some mallocmargin */ static int comp_names(struct fileinfo *a,struct fileinfo *b); @@ -74,7 +81,13 @@ void my_dirend(MY_DIR *buffer) { DBUG_ENTER("my_dirend"); if (buffer) + { + delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer + + ALIGN_SIZE(sizeof(MY_DIR)))); + free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0)); my_free((gptr) buffer,MYF(0)); + } DBUG_VOID_RETURN; } /* my_dirend */ @@ -91,14 +104,14 @@ static int comp_names(struct fileinfo *a, struct fileinfo *b) MY_DIR *my_dir(const char *path, myf MyFlags) { + char *buffer; + MY_DIR *result= 0; + FILEINFO finfo; + DYNAMIC_ARRAY *dir_entries_storage; + MEM_ROOT *names_storage; DIR *dirp; struct dirent *dp; - struct fileinfo *fnames; - char *buffer, *obuffer, *tempptr; - uint fcnt,i,size,firstfcnt, maxfcnt,length; char tmp_path[FN_REFLEN+1],*tmp_file; - my_ptrdiff_t diff; - bool eof; #ifdef THREAD char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1]; #endif @@ -110,74 +123,72 @@ MY_DIR *my_dir(const char *path, myf MyFlags) #endif dirp = opendir(directory_file_name(tmp_path,(my_string) path)); - size = STARTSIZE; #if defined(__amiga__) if ((dirp->dd_fd) < 0) /* Directory doesn't exists */ goto error; #endif - if (dirp == NULL || ! (buffer = (char *) my_malloc(size, MyFlags))) + if (dirp == NULL || + ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + + sizeof(MEM_ROOT), MyFlags))) goto error; - fcnt = 0; + dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); + names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); + + if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), + ENTRIES_START_SIZE, ENTRIES_INCREMENT)) + { + my_free((gptr) buffer,MYF(0)); + goto error; + } + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + + /* MY_DIR structure is allocated and completly initialized at this point */ + result= (MY_DIR*)buffer; + tmp_file=strend(tmp_path); - firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) / - (sizeof(struct fileinfo) + FN_LEN); - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr = (char *) (fnames + maxfcnt); #ifdef THREAD dp= (struct dirent*) dirent_tmp; #else dp=0; #endif - eof=0; - for (;;) + + while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp))) { - while (fcnt < maxfcnt && - !(eof= READDIR(dirp,(struct dirent*) dirent_tmp,dp))) + if (!(finfo.name= strdup_root(names_storage, dp->d_name))) + goto error; + + if (MyFlags & MY_WANT_STAT) { - bzero((gptr) (fnames+fcnt),sizeof(fnames[0])); /* for purify */ - fnames[fcnt].name = tempptr; - tempptr = strmov(tempptr,dp->d_name) + 1; - if (MyFlags & MY_WANT_STAT) - { - VOID(strmov(tmp_file,dp->d_name)); - VOID(my_stat(tmp_path, &fnames[fcnt].mystat, MyFlags)); - } - ++fcnt; + if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, + sizeof(MY_STAT)))) + goto error; + + bzero(finfo.mystat, sizeof(MY_STAT)); + VOID(strmov(tmp_file,dp->d_name)); + VOID(my_stat(tmp_path, finfo.mystat, MyFlags)); } - if (eof) - break; - size += STARTSIZE; obuffer = buffer; - if (!(buffer = (char *) my_realloc((gptr) buffer, size, - MyFlags | MY_FREE_ON_ERROR))) - goto error; /* No memory */ - length= (uint) (sizeof(struct fileinfo ) * firstfcnt); - diff= PTR_BYTE_DIFF(buffer , obuffer) + (int) length; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr= ADD_TO_PTR(tempptr,diff,char*); - for (i = 0; i < maxfcnt; i++) - fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*); + else + finfo.mystat= NULL; - /* move filenames upp a bit */ - maxfcnt += firstfcnt; - bmove_upp(tempptr,tempptr-length, - (uint) (tempptr- (char*) (fnames+maxfcnt))); + if (push_dynamic(dir_entries_storage, (gptr)&finfo)) + goto error; } (void) closedir(dirp); - { - MY_DIR * s = (MY_DIR *) buffer; - s->number_off_files = (uint) fcnt; - s->dir_entry = fnames; - } - if (!(MyFlags & MY_DONT_SORT)) - qsort((void *) fnames, (size_s) fcnt, sizeof(struct fileinfo), - (qsort_cmp) comp_names); #if defined(THREAD) && !defined(HAVE_READDIR_R) pthread_mutex_unlock(&THR_LOCK_open); #endif - DBUG_RETURN((MY_DIR *) buffer); + result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; + result->number_off_files= dir_entries_storage->elements; + + if (!(MyFlags & MY_DONT_SORT)) + qsort((void *) result->dir_entry, result->number_off_files, + sizeof(FILEINFO), (qsort_cmp) comp_names); + DBUG_RETURN(result); error: #if defined(THREAD) && !defined(HAVE_READDIR_R) @@ -186,6 +197,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) my_errno=errno; if (dirp) (void) closedir(dirp); + my_dirend(result); if (MyFlags & (MY_FAE | MY_WME)) my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno); DBUG_RETURN((MY_DIR *) NULL); @@ -349,10 +361,11 @@ my_string directory_file_name (my_string dst, const char *src) MY_DIR *my_dir(const char *path, myf MyFlags) { - struct fileinfo *fnames; - char *buffer, *obuffer, *tempptr; - int eof,i,fcnt,firstfcnt,length,maxfcnt; - uint size; + char *buffer; + MY_DIR *result= 0; + FILEINFO finfo; + DYNAMIC_ARRAY *dir_entries_storage; + MEM_ROOT *names_storage; #ifdef __BORLANDC__ struct ffblk find; #else @@ -360,7 +373,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags) #endif ushort mode; char tmp_path[FN_REFLEN],*tmp_file,attrib; - my_ptrdiff_t diff; #ifdef _WIN64 __int64 handle; #else @@ -392,85 +404,88 @@ MY_DIR *my_dir(const char *path, myf MyFlags) goto error; #endif - size = STARTSIZE; - firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) / - (sizeof(struct fileinfo) + FN_LEN); - if ((buffer = (char *) my_malloc(size, MyFlags)) == 0) + if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + + sizeof(MEM_ROOT), MyFlags))) goto error; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr = (char *) (fnames + maxfcnt); - fcnt = 0; - for (;;) + dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); + names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); + + if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), + ENTRIES_START_SIZE, ENTRIES_INCREMENT)) + { + my_free((gptr) buffer,MYF(0)); + goto error; + } + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + + /* MY_DIR structure is allocated and completly initialized at this point */ + result= (MY_DIR*)buffer; + + do { - do - { - fnames[fcnt].name = tempptr; #ifdef __BORLANDC__ - tempptr = strmov(tempptr,find.ff_name) + 1; - fnames[fcnt].mystat.st_size=find.ff_fsize; - fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0; + if (!(finfo.name= strdup_root(names_storage, find.ff_name))) + goto error; +#else + if (!(finfo.name= strdup_root(names_storage, find.name))) + goto error; +#endif + if (MyFlags & MY_WANT_STAT) + { + if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, + sizeof(MY_STAT)))) + goto error; + + bzero(finfo.mystat, sizeof(MY_STAT)); +#ifdef __BORLANDC__ + finfo.mystat->st_size=find.ff_fsize; mode=MY_S_IREAD; attrib=find.ff_attrib; #else - tempptr = strmov(tempptr,find.name) + 1; - fnames[fcnt].mystat.st_size=find.size; - fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0; + finfo.mystat->st_size=find.size; mode=MY_S_IREAD; attrib=find.attrib; #endif if (!(attrib & _A_RDONLY)) mode|=MY_S_IWRITE; if (attrib & _A_SUBDIR) mode|=MY_S_IFDIR; - fnames[fcnt].mystat.st_mode=mode; + finfo.mystat->st_mode=mode; #ifdef __BORLANDC__ - fnames[fcnt].mystat.st_mtime=((uint32) find.ff_ftime); + finfo.mystat->st_mtime=((uint32) find.ff_ftime); #else - fnames[fcnt].mystat.st_mtime=((uint32) find.time_write); -#endif - ++fcnt; -#ifdef __BORLANDC__ - } while ((eof= findnext(&find)) == 0 && fcnt < maxfcnt); -#else - } while ((eof= _findnext(handle,&find)) == 0 && fcnt < maxfcnt); + finfo.mystat->st_mtime=((uint32) find.time_write); #endif + } + else + finfo.mystat= NULL; - DBUG_PRINT("test",("eof: %d errno: %d",eof,errno)); - if (eof) - break; - size += STARTSIZE; obuffer = buffer; - if (!(buffer = (char *) my_realloc((gptr) buffer, size, - MyFlags | MY_FREE_ON_ERROR))) + if (push_dynamic(dir_entries_storage, (gptr)&finfo)) goto error; - length= sizeof(struct fileinfo ) * firstfcnt; - diff= PTR_BYTE_DIFF(buffer , obuffer) +length; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr= ADD_TO_PTR(tempptr,diff,char*); - for (i = 0; i < maxfcnt; i++) - fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*); - - /* move filenames upp a bit */ - maxfcnt += firstfcnt; - bmove_upp(tempptr,ADD_TO_PTR(tempptr,-length,char*), - (int) PTR_BYTE_DIFF(tempptr,fnames+maxfcnt)); - } - { - MY_DIR * s = (MY_DIR *) buffer; - s->number_off_files = (uint) fcnt; - s->dir_entry = fnames; - } - if (!(MyFlags & MY_DONT_SORT)) - qsort(fnames,fcnt,sizeof(struct fileinfo),(qsort_cmp) comp_names); -#ifndef __BORLANDC__ + +#ifdef __BORLANDC__ + } while (findnext(&find) == 0); +#else + } while (_findnext(handle,&find) == 0); + _findclose(handle); #endif - DBUG_RETURN((MY_DIR *) buffer); + result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; + result->number_off_files= dir_entries_storage->elements; + + if (!(MyFlags & MY_DONT_SORT)) + qsort((void *) result->dir_entry, result->number_off_files, + sizeof(FILEINFO), (qsort_cmp) comp_names); + DBUG_RETURN(result); error: my_errno=errno; #ifndef __BORLANDC__ if (handle != -1) _findclose(handle); #endif + my_dirend(result); if (MyFlags & MY_FAE+MY_WME) my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno); DBUG_RETURN((MY_DIR *) NULL); @@ -485,14 +500,14 @@ error: MY_DIR *my_dir(const char* path, myf MyFlags) { - struct fileinfo *fnames; - char *buffer, *obuffer, *tempptr; - int eof,i,fcnt,firstfcnt,length,maxfcnt; - uint size; + char *buffer; + MY_DIR *result= 0; + FILEINFO finfo; + DYNAMIC_ARRAY *dir_entries_storage; + MEM_ROOT *names_storage; struct find_t find; ushort mode; char tmp_path[FN_REFLEN],*tmp_file,attrib; - my_ptrdiff_t diff; DBUG_ENTER("my_dir"); DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags)); @@ -514,63 +529,65 @@ MY_DIR *my_dir(const char* path, myf MyFlags) if (_dos_findfirst(tmp_path,_A_NORMAL | _A_SUBDIR, &find)) goto error; - size = STARTSIZE; - firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) / - (sizeof(struct fileinfo) + FN_LEN); - if ((buffer = (char *) my_malloc(size, MyFlags)) == 0) + if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + + sizeof(MEM_ROOT), MyFlags))) goto error; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr = (char *) (fnames + maxfcnt); - fcnt = 0; - for (;;) + dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); + names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); + + if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), + ENTRIES_START_SIZE, ENTRIES_INCREMENT)) { - do - { - fnames[fcnt].name = tempptr; - tempptr = strmov(tempptr,find.name) + 1; - fnames[fcnt].mystat.st_size=find.size; - fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0; - mode=MY_S_IREAD; attrib=find.attrib; - if (!(attrib & _A_RDONLY)) - mode|=MY_S_IWRITE; - if (attrib & _A_SUBDIR) - mode|=MY_S_IFDIR; - fnames[fcnt].mystat.st_mode=mode; - fnames[fcnt].mystat.st_mtime=((uint32) find.wr_date << 16) + - find.wr_time; - ++fcnt; - } while ((eof= _dos_findnext(&find)) == 0 && fcnt < maxfcnt); - - DBUG_PRINT("test",("eof: %d errno: %d",eof,errno)); - if (eof) - break; - size += STARTSIZE; obuffer = buffer; - if (!(buffer = (char *) my_realloc((gptr) buffer, size, - MyFlags | MY_FREE_ON_ERROR))) + my_free((gptr) buffer,MYF(0)); + goto error; + } + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + + /* MY_DIR structure is allocated and completly initialized at this point */ + result= (MY_DIR*)buffer; + + do + { + if (!(finfo.name= strdup_root(names_storage, find.name))) goto error; - length= sizeof(struct fileinfo ) * firstfcnt; - diff= PTR_BYTE_DIFF(buffer , obuffer) +length; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr= ADD_TO_PTR(tempptr,diff,char*); - for (i = 0; i < maxfcnt; i++) - fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*); + + if (MyFlags & MY_WANT_STAT) + { + if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, + sizeof(MY_STAT)))) + goto error; + + bzero(finfo.mystat, sizeof(MY_STAT)); + finfo.mystat->st_size= find.size; + mode= MY_S_IREAD; attrib= find.attrib; + if (!(attrib & _A_RDONLY)) + mode|= MY_S_IWRITE; + if (attrib & _A_SUBDIR) + mode|= MY_S_IFDIR; + finfo.mystat->st_mode= mode; + finfo.mystat->st_mtime= ((uint32) find.wr_date << 16) + find.wr_time; + } + else + finfo.mystat= NULL; - /* move filenames upp a bit */ - maxfcnt += firstfcnt; - bmove_upp(tempptr,ADD_TO_PTR(tempptr,-length,char*), - (int) PTR_BYTE_DIFF(tempptr,fnames+maxfcnt)); - } - { - MY_DIR * s = (MY_DIR *) buffer; - s->number_off_files = (uint) fcnt; - s->dir_entry = fnames; - } + if (push_dynamic(dir_entries_storage, (gptr)&finfo)) + goto error; + + } while (_dos_findnext(&find) == 0); + + result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; + result->number_off_files= dir_entries_storage->elements; + if (!(MyFlags & MY_DONT_SORT)) - qsort(fnames,fcnt,sizeof(struct fileinfo),(qsort_cmp) comp_names); - DBUG_RETURN((MY_DIR *) buffer); + qsort((void *) result->dir_entry, result->number_off_files, + sizeof(FILEINFO), (qsort_cmp) comp_names); + DBUG_RETURN(result); error: + my_dirend(result); if (MyFlags & MY_FAE+MY_WME) my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno); DBUG_RETURN((MY_DIR *) NULL); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index cb6cd18b7c8..1a2f900eb7e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -213,7 +213,7 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, else #endif { - if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat.st_mode) || + if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat->st_mode) || (wild && wild_compare(file->name,wild))) continue; } From d3d9b727ebffa8b010638f9a519cfb8558e8d87f Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Fri, 12 Dec 2003 07:51:21 +0200 Subject: [PATCH 50/89] Many files: Fix assertion failure on line 713 of row0upd.c if there is a column prefix index and the last characters in the prefix are spaces: do not assume that the length of alphabetically equal strings is the same; fix a buglet which could cause InnoDB to think that a secondary index record was not locked though it had been updated in a way which did not alpahabetically change its value, e.g., abc -> aBc --- innobase/btr/btr0cur.c | 104 ++++++++-------------------------- innobase/include/btr0cur.h | 16 ------ innobase/include/row0upd.h | 31 ++++++++-- innobase/include/sync0sync.ic | 2 + innobase/lock/lock0lock.c | 6 ++ innobase/row/row0ins.c | 25 ++++++-- innobase/row/row0sel.c | 8 +-- innobase/row/row0upd.c | 80 ++++++++++++++++++++++++-- innobase/row/row0vers.c | 27 +++++++-- 9 files changed, 181 insertions(+), 118 deletions(-) diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index 29a8fd44b9e..bd09895656c 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -1146,7 +1146,6 @@ btr_cur_pessimistic_insert( } /*==================== B-TREE UPDATE =========================*/ -/* Only clustered index records are modified using these functions */ /***************************************************************** For an update, checks the locks and does the undo logging. */ @@ -1170,12 +1169,15 @@ btr_cur_upd_lock_and_undo( ut_ad(cursor && update && thr && roll_ptr); - /* Only clustered index records are updated using this function */ - ut_ad((cursor->index)->type & DICT_CLUSTERED); - rec = btr_cur_get_rec(cursor); index = cursor->index; + if (!(index->type & DICT_CLUSTERED)) { + /* We do undo logging only when we update a clustered index + record */ + return(lock_sec_rec_modify_check_and_lock(0, rec, index, thr)); + } + /* Check if we have to wait for a lock: enqueue an explicit lock request if yes */ @@ -1222,6 +1224,13 @@ btr_cur_update_in_place_log( mach_write_to_1(log_ptr, flags); log_ptr++; + /* The code below assumes index is a clustered index: change index to + the clustered index if we are updating a secondary index record (or we + could as well skip writing the sys col values to the log in this case + because they are not needed for a secondary index record update) */ + + index = dict_table_get_first_index(index->table); + log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr, mtr); mach_write_to_2(log_ptr, rec - buf_frame_align(rec)); @@ -1308,68 +1317,7 @@ btr_cur_parse_update_in_place( } /***************************************************************** -Updates a secondary index record when the update causes no size -changes in its fields. The only case when this function is currently -called is that in a char field characters change to others which -are identified in the collation order. */ - -ulint -btr_cur_update_sec_rec_in_place( -/*============================*/ - /* out: DB_SUCCESS or error number */ - btr_cur_t* cursor, /* in: cursor on the record to update; - cursor stays valid and positioned on the - same record */ - upd_t* update, /* in: update vector */ - que_thr_t* thr, /* in: query thread */ - mtr_t* mtr) /* in: mtr */ -{ - dict_index_t* index = cursor->index; - dict_index_t* clust_index; - ulint err; - rec_t* rec; - dulint roll_ptr = ut_dulint_zero; - trx_t* trx = thr_get_trx(thr); - - /* Only secondary index records are updated using this function */ - ut_ad(0 == (index->type & DICT_CLUSTERED)); - - rec = btr_cur_get_rec(cursor); - - if (btr_cur_print_record_ops && thr) { - printf( - "Trx with id %lu %lu going to update table %s index %s\n", - ut_dulint_get_high(thr_get_trx(thr)->id), - ut_dulint_get_low(thr_get_trx(thr)->id), - index->table_name, index->name); - rec_print(rec); - } - - err = lock_sec_rec_modify_check_and_lock(0, rec, index, thr); - - if (err != DB_SUCCESS) { - - return(err); - } - - /* Remove possible hash index pointer to this record */ - btr_search_update_hash_on_delete(cursor); - - row_upd_rec_in_place(rec, update); - - clust_index = dict_table_get_first_index(index->table); - - /* Note that roll_ptr is really just a dummy value since - a secondary index record does not contain any sys columns */ - - btr_cur_update_in_place_log(BTR_KEEP_SYS_FLAG, rec, clust_index, - update, trx, roll_ptr, mtr); - return(DB_SUCCESS); -} - -/***************************************************************** -Updates a record when the update causes no size changes in its fields. -We assume here that the ordering fields of the record do not change. */ +Updates a record when the update causes no size changes in its fields. */ ulint btr_cur_update_in_place( @@ -1389,13 +1337,10 @@ btr_cur_update_in_place( buf_block_t* block; ulint err; rec_t* rec; - dulint roll_ptr; + dulint roll_ptr = ut_dulint_zero; trx_t* trx; ibool was_delete_marked; - /* Only clustered index records are updated using this function */ - ut_ad(cursor->index->type & DICT_CLUSTERED); - rec = btr_cur_get_rec(cursor); index = cursor->index; trx = thr_get_trx(thr); @@ -1420,7 +1365,12 @@ btr_cur_update_in_place( block = buf_block_align(rec); if (block->is_hashed) { - if (row_upd_changes_ord_field_binary(NULL, index, update)) { + /* The function row_upd_changes_ord_field_binary works only + if the update vector was built for a clustered index, we must + NOT call it if index is secondary */ + + if (!(index->type & DICT_CLUSTERED) + || row_upd_changes_ord_field_binary(NULL, index, update)) { /* Remove possible hash index pointer to this record */ btr_search_update_hash_on_delete(cursor); @@ -1494,9 +1444,6 @@ btr_cur_optimistic_update( mem_heap_t* heap; ibool reorganized = FALSE; ulint i; - - /* Only clustered index records are updated using this function */ - ut_ad((cursor->index)->type & DICT_CLUSTERED); page = btr_cur_get_page(cursor); rec = btr_cur_get_rec(cursor); @@ -1546,8 +1493,8 @@ btr_cur_optimistic_update( new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); - row_upd_index_replace_new_col_vals(new_entry, index, update, NULL); - + row_upd_index_replace_new_col_vals_index_pos(new_entry, index, update, + NULL); old_rec_size = rec_get_size(rec); new_rec_size = rec_get_converted_size(new_entry); @@ -1729,7 +1676,6 @@ btr_cur_pessimistic_update( index = cursor->index; tree = index->tree; - ut_ad(index->type & DICT_CLUSTERED); ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, buf_block_align(page), @@ -1779,8 +1725,8 @@ btr_cur_pessimistic_update( new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); - row_upd_index_replace_new_col_vals(new_entry, index, update, heap); - + row_upd_index_replace_new_col_vals_index_pos(new_entry, index, update, + heap); if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR, roll_ptr); diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h index 506877333c3..31aecef8104 100644 --- a/innobase/include/btr0cur.h +++ b/innobase/include/btr0cur.h @@ -188,22 +188,6 @@ btr_cur_pessimistic_insert( que_thr_t* thr, /* in: query thread or NULL */ mtr_t* mtr); /* in: mtr */ /***************************************************************** -Updates a secondary index record when the update causes no size -changes in its fields. The only case when this function is currently -called is that in a char field characters change to others which -are identified in the collation order. */ - -ulint -btr_cur_update_sec_rec_in_place( -/*============================*/ - /* out: DB_SUCCESS or error number */ - btr_cur_t* cursor, /* in: cursor on the record to update; - cursor stays valid and positioned on the - same record */ - upd_t* update, /* in: update vector */ - que_thr_t* thr, /* in: query thread */ - mtr_t* mtr); /* in: mtr */ -/***************************************************************** Updates a record when the update causes no size changes in its fields. */ ulint diff --git a/innobase/include/row0upd.h b/innobase/include/row0upd.h index 473c55c7ef9..174f1158ea4 100644 --- a/innobase/include/row0upd.h +++ b/innobase/include/row0upd.h @@ -171,13 +171,31 @@ row_upd_build_difference_binary( Replaces the new column values stored in the update vector to the index entry given. */ +void +row_upd_index_replace_new_col_vals_index_pos( +/*=========================================*/ + dtuple_t* entry, /* in/out: index entry where replaced */ + dict_index_t* index, /* in: index; NOTE that this may also be a + non-clustered index */ + upd_t* update, /* in: an update vector built for the index so + that the field number in an upd_field is the + index position */ + mem_heap_t* heap); /* in: memory heap to which we allocate and + copy the new values, set this as NULL if you + do not want allocation */ +/*************************************************************** +Replaces the new column values stored in the update vector to the index entry +given. */ + void row_upd_index_replace_new_col_vals( /*===============================*/ dtuple_t* entry, /* in/out: index entry where replaced */ - dict_index_t* index, /* in: index; NOTE that may also be a + dict_index_t* index, /* in: index; NOTE that this may also be a non-clustered index */ - upd_t* update, /* in: update vector */ + upd_t* update, /* in: an update vector built for the + CLUSTERED index so that the field number in + an upd_field is the clustered index position */ mem_heap_t* heap); /* in: memory heap to which we allocate and copy the new values, set this as NULL if you do not want allocation */ @@ -199,7 +217,9 @@ row_upd_changes_ord_field_binary( known when this function is called, e.g., at compile time */ dict_index_t* index, /* in: index of the record */ - upd_t* update);/* in: update vector for the row */ + upd_t* update);/* in: update vector for the row; NOTE: the + field numbers in this MUST be clustered index + positions! */ /*************************************************************** Checks if an update vector changes an ordering field of an index record. This function is fast if the update vector is short or the number of ordering @@ -271,7 +291,10 @@ row_upd_index_parse( /* Update vector field */ struct upd_field_struct{ - ulint field_no; /* field number in the clustered + ulint field_no; /* field number in an index, usually + the clustered index, but in upadating + a secondary index record in btr0cur.c + this is the position in the secondary index */ que_node_t* exp; /* expression for calculating a new value: it refers to column values and diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic index c11cc0d196e..a9b511a7593 100644 --- a/innobase/include/sync0sync.ic +++ b/innobase/include/sync0sync.ic @@ -257,6 +257,8 @@ mutex_enter_func( mutex->file_name = file_name; mutex->line = line; + mutex->thread_id = os_thread_get_curr_id(); + return; /* Succeeded! */ } diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 3f9b5316185..4b39368c540 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -339,6 +339,11 @@ lock_deadlock_recursive( ulint* cost); /* in/out: number of calculation steps thus far: if this exceeds LOCK_MAX_N_STEPS_... we return TRUE */ + +#define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex) +#define lock_mutex_exit_kernel() mutex_exit(&kernel_mutex) + +#ifdef notdefined /************************************************************************* Reserves the kernel mutex. This function is used in this module to allow monitoring the contention degree on the kernel mutex caused by the lock @@ -362,6 +367,7 @@ lock_mutex_exit_kernel(void) { mutex_exit(&kernel_mutex); } +#endif #ifdef notdefined diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index e02859bc851..45c5897eee7 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -225,11 +225,15 @@ ulint row_ins_sec_index_entry_by_modify( /*==============================*/ /* out: DB_SUCCESS or error code */ + ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE, + depending on whether mtr holds just a leaf + latch or also a tree latch */ btr_cur_t* cursor, /* in: B-tree cursor */ dtuple_t* entry, /* in: index entry to insert */ que_thr_t* thr, /* in: query thread */ mtr_t* mtr) /* in: mtr */ { + big_rec_t* dummy_big_rec; mem_heap_t* heap; upd_t* update; rec_t* rec; @@ -241,16 +245,28 @@ row_ins_sec_index_entry_by_modify( ut_ad(rec_get_deleted_flag(rec)); /* We know that in the alphabetical ordering, entry and rec are - identical. But in their binary form there may be differences if + identified. But in their binary form there may be differences if there are char fields in them. Therefore we have to calculate the - difference and do an update-in-place if necessary. */ + difference. */ heap = mem_heap_create(1024); update = row_upd_build_sec_rec_difference_binary(cursor->index, entry, rec, heap); + if (mode == BTR_MODIFY_LEAF) { + /* Try an optimistic updating of the record, keeping changes + within the page */ - err = btr_cur_update_sec_rec_in_place(cursor, update, thr, mtr); + err = btr_cur_optimistic_update(BTR_KEEP_SYS_FLAG, cursor, + update, 0, thr, mtr); + if (err == DB_OVERFLOW || err == DB_UNDERFLOW) { + err = DB_FAIL; + } + } else { + ut_a(mode == BTR_MODIFY_TREE); + err = btr_cur_pessimistic_update(BTR_KEEP_SYS_FLAG, cursor, + &dummy_big_rec, update, 0, thr, mtr); + } mem_heap_free(heap); @@ -1829,7 +1845,8 @@ row_ins_index_entry_low( ext_vec, n_ext_vec, thr, &mtr); } else { - err = row_ins_sec_index_entry_by_modify(&cursor, entry, + err = row_ins_sec_index_entry_by_modify(mode, &cursor, + entry, thr, &mtr); } diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index f02fbeeb8fd..27d27b75a1c 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -51,7 +51,8 @@ to que_run_threads: this is to allow canceling runaway queries */ /************************************************************************ Returns TRUE if the user-defined column values in a secondary index record -are the same as the corresponding columns in the clustered index record. +are alphabetically the same as the corresponding columns in the clustered +index record. NOTE: the comparison is NOT done as a binary comparison, but character fields are compared with collation! */ static @@ -96,11 +97,6 @@ row_sel_sec_rec_is_for_clust_rec( clust_len = ifield->prefix_len; } - if (sec_len != clust_len) { - - return(FALSE); - } - if (0 != cmp_data_data(dict_col_get_type(col), clust_field, clust_len, sec_field, sec_len)) { diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index db68479509d..3de0a4019d1 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -698,7 +698,7 @@ row_upd_build_sec_rec_difference_binary( ulint i; /* This function is used only for a secondary index */ - ut_ad(0 == (index->type & DICT_CLUSTERED)); + ut_a(0 == (index->type & DICT_CLUSTERED)); update = upd_create(dtuple_get_n_fields(entry), heap); @@ -710,7 +710,13 @@ row_upd_build_sec_rec_difference_binary( dfield = dtuple_get_nth_field(entry, i); - ut_a(len == dfield_get_len(dfield)); + /* NOTE that it may be that len != dfield_get_len(dfield) if we + are updating in a character set and collation where strings of + different length can be equal in an alphabetical comparison, + and also in the case where we have a column prefix index + and the last characters in the index field are spaces; the + latter case probably caused the assertion failures reported at + row0upd.c line 713 in versions 4.0.14 - 4.0.16. */ /* NOTE: we compare the fields as binary strings! (No collation) */ @@ -819,13 +825,77 @@ skip_compare: Replaces the new column values stored in the update vector to the index entry given. */ +void +row_upd_index_replace_new_col_vals_index_pos( +/*=========================================*/ + dtuple_t* entry, /* in/out: index entry where replaced */ + dict_index_t* index, /* in: index; NOTE that this may also be a + non-clustered index */ + upd_t* update, /* in: an update vector built for the index so + that the field number in an upd_field is the + index position */ + mem_heap_t* heap) /* in: memory heap to which we allocate and + copy the new values, set this as NULL if you + do not want allocation */ +{ + dict_field_t* field; + upd_field_t* upd_field; + dfield_t* dfield; + dfield_t* new_val; + ulint j; + ulint i; + + ut_ad(index); + + dtuple_set_info_bits(entry, update->info_bits); + + for (j = 0; j < dict_index_get_n_fields(index); j++) { + + field = dict_index_get_nth_field(index, j); + + for (i = 0; i < upd_get_n_fields(update); i++) { + + upd_field = upd_get_nth_field(update, i); + + if (upd_field->field_no == j) { + + dfield = dtuple_get_nth_field(entry, j); + + new_val = &(upd_field->new_val); + + dfield_set_data(dfield, new_val->data, + new_val->len); + if (heap && new_val->len != UNIV_SQL_NULL) { + dfield->data = mem_heap_alloc(heap, + new_val->len); + ut_memcpy(dfield->data, new_val->data, + new_val->len); + } + + if (field->prefix_len > 0 + && new_val->len != UNIV_SQL_NULL + && new_val->len > field->prefix_len) { + + dfield->len = field->prefix_len; + } + } + } + } +} + +/*************************************************************** +Replaces the new column values stored in the update vector to the index entry +given. */ + void row_upd_index_replace_new_col_vals( /*===============================*/ dtuple_t* entry, /* in/out: index entry where replaced */ dict_index_t* index, /* in: index; NOTE that this may also be a non-clustered index */ - upd_t* update, /* in: update vector */ + upd_t* update, /* in: an update vector built for the + CLUSTERED index so that the field number in + an upd_field is the clustered index position */ mem_heap_t* heap) /* in: memory heap to which we allocate and copy the new values, set this as NULL if you do not want allocation */ @@ -893,7 +963,9 @@ row_upd_changes_ord_field_binary( known when this function is called, e.g., at compile time */ dict_index_t* index, /* in: index of the record */ - upd_t* update) /* in: update vector for the row */ + upd_t* update) /* in: update vector for the row; NOTE: the + field numbers in this MUST be clustered index + positions! */ { upd_field_t* upd_field; dict_field_t* ind_field; diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c index d4a463d8a96..fca56389e45 100644 --- a/innobase/row/row0vers.c +++ b/innobase/row/row0vers.c @@ -117,9 +117,10 @@ row_vers_impl_x_locked_off_kernel( return(NULL); } - /* We look up if some earlier version of the clustered index record - would require rec to be in a different state (delete marked or - unmarked, or not existing). If there is such a version, then rec was + /* We look up if some earlier version, which was modified by the trx_id + transaction, of the clustered index record would require rec to be in + a different state (delete marked or unmarked, or have different field + values, or not existing). If there is such a version, then rec was modified by the trx_id transaction, and it has an implicit x-lock on rec. Note that if clust_rec itself would require rec to be in a different state, then the trx_id transaction has not yet had time to @@ -188,6 +189,8 @@ row_vers_impl_x_locked_off_kernel( vers_del = rec_get_deleted_flag(prev_version); + /* We check if entry and rec are identified in the alphabetical + ordering */ if (0 == cmp_dtuple_rec(entry, rec)) { /* The delete marks of rec and prev_version should be equal for rec to be in the state required by @@ -198,6 +201,20 @@ row_vers_impl_x_locked_off_kernel( break; } + + /* It is possible that the row was updated so that the + secondary index record remained the same in + alphabetical ordering, but the field values changed + still. For example, 'abc' -> 'ABC'. Check also that. */ + + dtuple_set_types_binary(entry, + dtuple_get_n_fields(entry)); + if (0 != cmp_dtuple_rec(entry, rec)) { + + trx = trx_get_on_id(trx_id); + + break; + } } else if (!rec_del) { /* The delete mark should be set in rec for it to be in the state required by prev_version */ @@ -256,8 +273,8 @@ row_vers_must_preserve_del_marked( Finds out if a version of the record, where the version >= the current purge view, should have ientry as its secondary index entry. We check if there is any not delete marked version of the record where the trx -id >= purge view, and the secondary index entry == ientry; exactly in -this case we return TRUE. */ +id >= purge view, and the secondary index entry and ientry are identified in +the alphabetical ordering; exactly in this case we return TRUE. */ ibool row_vers_old_has_index_entry( From 75a662fb3caa78e96c51475013f694b000c8119d Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Fri, 12 Dec 2003 08:09:25 +0200 Subject: [PATCH 51/89] row0upd.h, row0upd.c: Remove wrong debug assertion and comment --- innobase/include/row0upd.h | 4 ++-- innobase/row/row0upd.c | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/innobase/include/row0upd.h b/innobase/include/row0upd.h index 174f1158ea4..dd989982743 100644 --- a/innobase/include/row0upd.h +++ b/innobase/include/row0upd.h @@ -123,8 +123,8 @@ row_upd_changes_field_size_or_external( /* out: TRUE if the update changes the size of some field in index or the field is external in rec or update */ - rec_t* rec, /* in: record in clustered index */ - dict_index_t* index, /* in: clustered index */ + rec_t* rec, /* in: record in index */ + dict_index_t* index, /* in: index */ upd_t* update);/* in: update vector */ /*************************************************************** Replaces the new column values stored in the update vector to the record diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 3de0a4019d1..e3725c8b39e 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -361,8 +361,8 @@ row_upd_changes_field_size_or_external( /* out: TRUE if the update changes the size of some field in index or the field is external in rec or update */ - rec_t* rec, /* in: record in clustered index */ - dict_index_t* index, /* in: clustered index */ + rec_t* rec, /* in: record in index */ + dict_index_t* index, /* in: index */ upd_t* update) /* in: update vector */ { upd_field_t* upd_field; @@ -372,8 +372,6 @@ row_upd_changes_field_size_or_external( ulint n_fields; ulint i; - ut_ad(index->type & DICT_CLUSTERED); - n_fields = upd_get_n_fields(update); for (i = 0; i < n_fields; i++) { From 5aaa6e61a60fe6398bc9e50bfce1b4bf1902a2bc Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 12 Dec 2003 18:00:54 +0400 Subject: [PATCH 52/89] Fix for #1224 in 4.0 we didn't specify thd->priv_host properly --- libmysqld/lib_sql.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index d33f384f81e..03e3c1fee30 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -224,6 +224,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, send_error(net,ER_OUT_OF_RESOURCES); return 1; } + strcpy(thd->priv_host, LOCAL_HOST); thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, passwd, thd->scramble, &thd->priv_user, thd->priv_host, From 1485d9b438757cf9ad5e6a822e6501568e4dcb44 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 12 Dec 2003 18:27:25 +0400 Subject: [PATCH 53/89] Edited fix for #1224. strcpy changed to strmake --- libmysqld/lib_sql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 03e3c1fee30..91a308ecb21 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -224,7 +224,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, send_error(net,ER_OUT_OF_RESOURCES); return 1; } - strcpy(thd->priv_host, LOCAL_HOST); + strmake(thd->priv_host, LOCAL_HOST, sizeof(thd->priv_host)-1); thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, passwd, thd->scramble, &thd->priv_user, thd->priv_host, From e6e0937dc45b9b4e179366098ea14c76120b6f5f Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 12 Dec 2003 21:26:20 +0400 Subject: [PATCH 54/89] Proposed fix for #2093 it happens because of the LEFT JOINT optimization in add_key_part() This optimization does exactly the same in JOIN and in WHERE conditions Not right. I moved that optimization one level upper. --- mysql-test/r/join_outer.result | 17 +++++++++++++++++ mysql-test/t/join_outer.test | 13 +++++++++++++ sql/sql_select.cc | 30 ++++++++++++++++++++++-------- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index debec01fbdc..ae4d99e6241 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -667,3 +667,20 @@ left outer join t2 using (f2) left outer join t3 using (f3); Unknown column 'test.t2.f3' in 'on clause' drop table t1,t2,t3; +create table t1 (a1 int, a2 int); +create table t2 (b1 int not null, b2 int); +create table t3 (c1 int, c2 int); +insert into t1 values (1,2), (2,2), (3,2); +insert into t2 values (1,3), (2,3); +insert into t3 values (2,4), (3,4); +select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null; +a1 a2 b1 b2 c1 c2 +1 2 1 3 NULL NULL +2 2 2 3 NULL NULL +3 2 NULL NULL 3 4 +explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null; +table type possible_keys key key_len ref rows Extra +t1 ALL NULL NULL NULL NULL 3 +t2 ALL NULL NULL NULL NULL 2 +t3 ALL NULL NULL NULL NULL 2 +drop table t1, t2, t3; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index ee7d55d2a4e..bed4d4b033b 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -437,3 +437,16 @@ select * from t1 left outer join t2 using (f2) left outer join t3 using (f3); drop table t1,t2,t3; + +create table t1 (a1 int, a2 int); +create table t2 (b1 int not null, b2 int); +create table t3 (c1 int, c2 int); + +insert into t1 values (1,2), (2,2), (3,2); +insert into t2 values (1,3), (2,3); +insert into t3 values (2,4), (3,4); + +select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null; +explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null; + +drop table t1, t2, t3; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 892ad02bb5b..d0d6c1e5fa2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1683,10 +1683,6 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field) } } } - /* Mark that we can optimize LEFT JOIN */ - if (key_field->val->type() == Item::NULL_ITEM && - !key_field->field->real_maybe_null()) - key_field->field->table->reginfo.not_exists_optimize=1; } @@ -1777,13 +1773,26 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, { KEY_FIELD *key_fields,*end; + KEY_FIELD *field; if (!(key_fields=(KEY_FIELD*) thd->alloc(sizeof(key_fields[0])*(thd->cond_count+1)*2))) return TRUE; /* purecov: inspected */ - and_level=0; end=key_fields; + and_level=0; field=end=key_fields; + if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64)) + return TRUE; if (cond) + { add_key_fields(join_tab,&end,&and_level,cond,normal_tables); + for (; field != end ; field++) + { + add_key_part(keyuse,field); + /* Mark that we can optimize LEFT JOIN */ + if (field->val->type() == Item::NULL_ITEM && + !field->field->real_maybe_null()) + field->field->table->reginfo.not_exists_optimize=1; + } + } for (i=0 ; i < tables ; i++) { if (join_tab[i].on_expr) @@ -1792,11 +1801,16 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, join_tab[i].table->map); } } - if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64)) - return TRUE; /* fill keyuse with found key parts */ - for (KEY_FIELD *field=key_fields ; field != end ; field++) + for (; field != end ; field++) + { add_key_part(keyuse,field); + /* Mark that we can optimize LEFT JOIN */ + if (field->field->table == join_tab->table && + field->val->type() == Item::NULL_ITEM && + !field->field->real_maybe_null()) + join_tab->table->reginfo.not_exists_optimize=1; + } } if (thd->lex.select->ftfunc_list.elements) From 0abfaa9840c4ddfaa98ef1160838f9627a8cf75f Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 12 Dec 2003 22:13:57 +0400 Subject: [PATCH 55/89] Fix #2093 Update after discussion with Monty --- sql/sql_select.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d0d6c1e5fa2..8f2d97affca 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1803,14 +1803,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, } /* fill keyuse with found key parts */ for (; field != end ; field++) - { add_key_part(keyuse,field); - /* Mark that we can optimize LEFT JOIN */ - if (field->field->table == join_tab->table && - field->val->type() == Item::NULL_ITEM && - !field->field->real_maybe_null()) - join_tab->table->reginfo.not_exists_optimize=1; - } } if (thd->lex.select->ftfunc_list.elements) From f995a5f4aa919d6d229d29fb652a263d8c816430 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Fri, 12 Dec 2003 22:26:58 +0200 Subject: [PATCH 56/89] Fix autoincrement for signed columns (Bug #1366) Fixed problem with char > 128 in QUOTE() function. (Bug #1868) Disable creation of symlinks if my_disable_symlink is set Fixed searching of TEXT with end space. (Bug #1651) Fixed caching bug in multi-table-update where same table was used twice. (Bug #1711) Fixed problem with UNIX_TIMESTAMP() for timestamps close to 0. (Bug #1998) Fixed timestamp.test --- include/my_base.h | 10 +- myisam/mi_check.c | 2 +- myisam/mi_key.c | 54 +++++-- myisam/mi_open.c | 3 +- myisam/mi_search.c | 25 ++- mysql-test/r/auto_increment.result | 26 ++++ mysql-test/r/binary.result | 1 + mysql-test/r/func_str.result | 3 + mysql-test/r/func_time.result | 9 ++ ...zone.require => have_met_timezone.require} | 2 +- mysql-test/r/innodb.result | 10 ++ mysql-test/r/multi_update.result | 10 ++ mysql-test/r/symlink.result | 20 +++ mysql-test/r/timezone.result | 6 + mysql-test/r/truncate.result | 9 ++ mysql-test/r/type_blob.result | 146 ++++++++++++++++++ mysql-test/t/auto_increment.test | 19 +++ mysql-test/t/func_str.test | 1 + mysql-test/t/func_time.test | 7 + mysql-test/t/innodb.test | 12 ++ mysql-test/t/multi_update.test | 10 ++ mysql-test/t/symlink.test | 22 +++ mysql-test/t/timezone.test | 10 +- mysql-test/t/truncate.test | 12 ++ mysql-test/t/type_blob.test | 49 ++++++ mysys/my_symlink2.c | 12 +- sql/field.h | 7 +- sql/ha_innodb.cc | 4 +- sql/item_strfunc.cc | 2 +- sql/mysql_priv.h | 1 + sql/opt_range.cc | 46 ++++-- sql/records.cc | 11 +- sql/sql_acl.cc | 4 +- sql/sql_parse.cc | 3 +- sql/sql_select.cc | 12 +- sql/sql_table.cc | 8 +- sql/sql_update.cc | 22 ++- sql/table.cc | 21 ++- sql/table.h | 2 +- sql/time.cc | 4 +- 40 files changed, 571 insertions(+), 66 deletions(-) rename mysql-test/r/{have_mest_timezone.require => have_met_timezone.require} (58%) diff --git a/include/my_base.h b/include/my_base.h index 91a248cd401..5344d876f99 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -180,11 +180,17 @@ enum ha_base_keytype { /* poor old NISAM has 8-bit flags :-( */ #define HA_SORT_ALLOWS_SAME 128 /* Intern bit when sorting records */ #endif +/* + Key has a part that can have end space. If this is an unique key + we have to handle it differently from other unique keys as we can find + many matching rows for one key (becaue end space are not compared) +*/ +#define HA_END_SPACE_KEY 4096 - /* These flags can be order to key-seg-flag */ + /* These flags can be added to key-seg-flag */ #define HA_SPACE_PACK 1 /* Pack space in key-seg */ -#define HA_PART_KEY 4 /* Used by MySQL for part-key-cols */ +#define HA_PART_KEY_SEG 4 /* Used by MySQL for part-key-cols */ #define HA_VAR_LENGTH 8 #define HA_NULL_PART 16 #define HA_BLOB_PART 32 diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 007ae950990..4ec6d6f6a7c 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -126,7 +126,7 @@ int chk_status(MI_CHECK *param, register MI_INFO *info) int chk_del(MI_CHECK *param, register MI_INFO *info, uint test_flag) { reg2 ha_rows i; - uint j,delete_link_length; + uint delete_link_length; my_off_t empty,next_link,old_link; char buff[22],buff2[22]; DBUG_ENTER("chk_del"); diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 89f6bc490fa..766ecf334b6 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -18,6 +18,7 @@ #include "myisamdef.h" #include "m_ctype.h" +#include #ifdef HAVE_IEEEFP_H #include #endif @@ -388,53 +389,86 @@ int _mi_read_key_record(MI_INFO *info, my_off_t filepos, byte *buf) return(-1); /* Wrong data to read */ } + +/* + Update auto_increment info - /* Update auto_increment info */ + SYNOPSIS + update_auto_increment() + info MyISAM handler + record Row to update + + IMPLEMENTATION + Only replace the auto_increment value if it is higher than the previous + one. For signed columns we don't update the auto increment value if it's + less than zero. +*/ void update_auto_increment(MI_INFO *info,const byte *record) { - ulonglong value; - MI_KEYSEG *keyseg=info->s->keyinfo[info->s->base.auto_key-1].seg; - const uchar *key=(uchar*) record+keyseg->start; + ulonglong value= 0; /* Store unsigned values here */ + longlong s_value= 0; /* Store signed values here */ + MI_KEYSEG *keyseg= info->s->keyinfo[info->s->base.auto_key-1].seg; + const uchar *key= (uchar*) record + keyseg->start; switch (keyseg->type) { case HA_KEYTYPE_INT8: + s_value= (longlong) *(char*)key; + break; case HA_KEYTYPE_BINARY: value=(ulonglong) *(uchar*) key; break; case HA_KEYTYPE_SHORT_INT: + s_value= (longlong) sint2korr(key); + break; case HA_KEYTYPE_USHORT_INT: value=(ulonglong) uint2korr(key); break; case HA_KEYTYPE_LONG_INT: + s_value= (longlong) sint4korr(key); + break; case HA_KEYTYPE_ULONG_INT: value=(ulonglong) uint4korr(key); break; case HA_KEYTYPE_INT24: + s_value= (longlong) sint3korr(key); + break; case HA_KEYTYPE_UINT24: value=(ulonglong) uint3korr(key); break; - case HA_KEYTYPE_FLOAT: /* This shouldn't be used */ + case HA_KEYTYPE_FLOAT: /* This shouldn't be used */ { float f_1; float4get(f_1,key); - value = (ulonglong) f_1; + /* Ignore negative values */ + value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1; break; } - case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */ + case HA_KEYTYPE_DOUBLE: /* This shouldn't be used */ { double f_1; float8get(f_1,key); - value = (ulonglong) f_1; + /* Ignore negative values */ + value = (f_1 < 0.0) ? 0 : (ulonglong) f_1; break; } case HA_KEYTYPE_LONGLONG: + s_value= sint8korr(key); + break; case HA_KEYTYPE_ULONGLONG: value= uint8korr(key); break; default: - value=0; /* Error */ + DBUG_ASSERT(0); + value=0; /* Error */ break; } - set_if_bigger(info->s->state.auto_increment,value); + + /* + The following code works becasue if s_value < 0 then value is 0 + and if s_value == 0 then value will contain either s_value or the + correct value. + */ + set_if_bigger(info->s->state.auto_increment, + (s_value > 0) ? (ulonglong) s_value : value); } diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 580261d8078..944a8af01e9 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -815,6 +815,8 @@ char *mi_state_info_read(char *ptr, MI_STATE_INFO *state) state->status = mi_uint4korr(ptr); ptr +=4; state->update_count=mi_uint4korr(ptr); ptr +=4; + ptr+= state->state_diff_length; + for (i=0; i < keys; i++) { state->key_root[i]= mi_sizekorr(ptr); ptr +=8; @@ -823,7 +825,6 @@ char *mi_state_info_read(char *ptr, MI_STATE_INFO *state) { state->key_del[i] = mi_sizekorr(ptr); ptr +=8; } - ptr+= state->state_diff_length; state->sec_index_changed = mi_uint4korr(ptr); ptr +=4; state->sec_index_used = mi_uint4korr(ptr); ptr +=4; state->version = mi_uint4korr(ptr); ptr +=4; diff --git a/myisam/mi_search.c b/myisam/mi_search.c index 423b15ff8f7..5d0750f6a82 100644 --- a/myisam/mi_search.c +++ b/myisam/mi_search.c @@ -783,7 +783,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a, if (piks && (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) + (my_bool) ((nextflag & SEARCH_PREFIX) && + next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a+=a_length; b+=b_length; @@ -801,7 +802,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a, } if (piks && (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) + (my_bool) ((nextflag & SEARCH_PREFIX) + && next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a=end; b+=length; @@ -817,7 +819,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a, if (piks && (flag=compare_bin(a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) + (my_bool) ((nextflag & SEARCH_PREFIX) && + next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a+=a_length; b+=b_length; @@ -828,7 +831,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a, uint length=keyseg->length; if (piks && (flag=compare_bin(a,length,b,length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) + (my_bool) ((nextflag & SEARCH_PREFIX) && + next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a+=length; b+=length; @@ -841,9 +845,17 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a, get_key_pack_length(b_length,pack_length,b); next_key_length=key_length-b_length-pack_length; + if (!(nextflag & (SEARCH_PREFIX | SEARCH_UPDATE))) + { + while (a_length && a[a_length-1] == ' ') + a_length--; + while (b_length && b[b_length-1] == ' ') + b_length--; + } if (piks && (flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) + (my_bool) ((nextflag & SEARCH_PREFIX) && + next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a+=a_length; b+=b_length; @@ -859,7 +871,8 @@ int _mi_key_cmp(register MI_KEYSEG *keyseg, register uchar *a, if (piks && (flag=compare_bin(a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) + (my_bool) ((nextflag & SEARCH_PREFIX) && + next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a+=a_length; b+=b_length; diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index e79e6aab56b..cbd2d48b38d 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -105,3 +105,29 @@ Table Op Msg_type Msg_text test.t1 check warning Found row where the auto_increment column has the value 0 test.t1 check status OK drop table t1; +create table t1 (a int not null auto_increment primary key); +insert into t1 values (NULL); +insert into t1 values (-1); +select last_insert_id(); +last_insert_id() +1 +insert into t1 values (NULL); +select * from t1; +a +-1 +1 +2 +drop table t1; +create table t1 (a int not null auto_increment primary key) /*!41002 type=heap */; +insert into t1 values (NULL); +insert into t1 values (-1); +select last_insert_id(); +last_insert_id() +1 +insert into t1 values (NULL); +select * from t1; +a +-1 +1 +2 +drop table t1; diff --git a/mysql-test/r/binary.result b/mysql-test/r/binary.result index 4d5eb62cc71..2de8b01bc3a 100644 --- a/mysql-test/r/binary.result +++ b/mysql-test/r/binary.result @@ -65,6 +65,7 @@ a b alter table t1 modify b tinytext not null, drop key b, add key (b(100)); select * from t1 where b="hello "; a b +hello hello select * from t1 ignore index (b) where b="hello "; a b hello hello diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index dcb788f520f..35a5ba70e86 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -164,6 +164,9 @@ NULL '\0\Z' select length(quote(concat(char(0),"test"))); length(quote(concat(char(0),"test"))) 8 +select hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235)))); +hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235)))) +27E0E3E6E7E8EAEB27 select reverse(""); reverse("") diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 61aa4306c61..4715227425e 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -431,3 +431,12 @@ select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2; start ctime1 ctime2 2002-11-04 00:00:00 2002-10-29 16:51:06 2002-11-05 16:47:31 drop table t1,t2,t3; +select @a:=FROM_UNIXTIME(1); +@a:=FROM_UNIXTIME(1) +1970-01-01 03:00:01 +select unix_timestamp(@a); +unix_timestamp(@a) +1 +select unix_timestamp('1969-12-01 19:00:01'); +unix_timestamp('1969-12-01 19:00:01') +0 diff --git a/mysql-test/r/have_mest_timezone.require b/mysql-test/r/have_met_timezone.require similarity index 58% rename from mysql-test/r/have_mest_timezone.require rename to mysql-test/r/have_met_timezone.require index 2a219f39b7e..4ab263e2c0d 100644 --- a/mysql-test/r/have_mest_timezone.require +++ b/mysql-test/r/have_met_timezone.require @@ -1,2 +1,2 @@ Variable_name Value -timezone MEST +timezone MET diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 3938fc80f10..ce5491a718f 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1233,3 +1233,13 @@ create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, pri insert into t2 select * from t1; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; drop table t1,t2; +SET AUTOCOMMIT=1; +create table t1 (a integer auto_increment primary key) type=innodb; +insert into t1 (a) values (NULL),(NULL); +truncate table t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +a +3 +4 +drop table t1; diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 350cea420b6..5486d9ec5f0 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -327,3 +327,13 @@ select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and a b a b 2 2 NULL NULL drop table t1,t2; +create table t1 (a int not null auto_increment primary key, b int not null); +insert into t1 (b) values (1),(2),(3),(4); +update t1, t1 as t2 set t1.b=t2.b+1 where t1.a=t2.a; +select * from t1; +a b +1 2 +2 3 +3 4 +4 5 +drop table t1; diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 2deecae7243..d07a8613883 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -64,3 +64,23 @@ t9 CREATE TABLE `t9` ( PRIMARY KEY (`a`) ) TYPE=MyISAM DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/' drop database mysqltest; +create table t1 (a int not null) type=myisam; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL default '0' +) TYPE=MyISAM +alter table t1 add b int; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL default '0', + `b` int(11) default NULL +) TYPE=MyISAM +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL default '0', + `b` int(11) default NULL +) TYPE=MyISAM +drop table t1; diff --git a/mysql-test/r/timezone.result b/mysql-test/r/timezone.result index b82b39da262..de75e649ee4 100644 --- a/mysql-test/r/timezone.result +++ b/mysql-test/r/timezone.result @@ -23,3 +23,9 @@ ts from_unixtime(ts) 1048989599 2003-03-30 03:59:59 1048989601 2003-03-30 04:00:01 DROP TABLE t1; +select @a:=FROM_UNIXTIME(1); +@a:=FROM_UNIXTIME(1) +1970-01-01 01:00:01 +select unix_timestamp(@a); +unix_timestamp(@a) +1 diff --git a/mysql-test/r/truncate.result b/mysql-test/r/truncate.result index ad390c9fa92..1b387214292 100644 --- a/mysql-test/r/truncate.result +++ b/mysql-test/r/truncate.result @@ -23,3 +23,12 @@ n drop table t1; truncate non_existing_table; Table 'test.non_existing_table' doesn't exist +create table t1 (a integer auto_increment primary key); +insert into t1 (a) values (NULL),(NULL); +truncate table t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +a +1 +2 +drop table t1; diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index d7c41743bf3..0bb9146fafc 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -455,3 +455,149 @@ select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1; if(imagem is null, "ERROR", "OK") length(imagem) OK 581 drop table t1; +create table t1 (id integer primary key auto_increment, txt text not null, unique index txt_index (txt (20))); +insert into t1 (txt) values ('Chevy'), ('Chevy '); +select * from t1 where txt='Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy ' or txt='Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where id='1' or id='2'; +id txt +1 Chevy +2 Chevy +insert into t1 (txt) values('Ford'); +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford'; +id txt +1 Chevy +2 Chevy +3 Ford +select * from t1 where txt='Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt in ('Chevy ','Chevy'); +id txt +1 Chevy +2 Chevy +select * from t1 where txt in ('Chevy'); +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt < 'Chevy '; +id txt +select * from t1 where txt <= 'Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt > 'Chevy'; +id txt +3 Ford +select * from t1 where txt >= 'Chevy'; +id txt +1 Chevy +2 Chevy +3 Ford +drop table t1; +create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20))); +insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); +select * from t1 where txt='Chevy' or txt is NULL; +id txt +3 NULL +1 Chevy +2 Chevy +select * from t1 where txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy ' or txt='Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where id='1' or id='2'; +id txt +1 Chevy +2 Chevy +insert into t1 (txt) values('Ford'); +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford'; +id txt +1 Chevy +2 Chevy +4 Ford +select * from t1 where txt='Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt in ('Chevy ','Chevy'); +id txt +1 Chevy +2 Chevy +select * from t1 where txt in ('Chevy'); +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt < 'Chevy '; +id txt +select * from t1 where txt < 'Chevy ' or txt is NULL; +id txt +3 NULL +select * from t1 where txt <= 'Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt > 'Chevy'; +id txt +4 Ford +select * from t1 where txt >= 'Chevy'; +id txt +1 Chevy +2 Chevy +4 Ford +drop table t1; diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index 5fba4bb9234..8c614131684 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -70,3 +70,22 @@ select * from t1; check table t1; drop table t1; +# +# Test negative values (Bug #1366) +# + +create table t1 (a int not null auto_increment primary key); +insert into t1 values (NULL); +insert into t1 values (-1); +select last_insert_id(); +insert into t1 values (NULL); +select * from t1; +drop table t1; + +create table t1 (a int not null auto_increment primary key) /*!41002 type=heap */; +insert into t1 values (NULL); +insert into t1 values (-1); +select last_insert_id(); +insert into t1 values (NULL); +select * from t1; +drop table t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index b07b0b635c1..33d89b3ca37 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -67,6 +67,7 @@ select quote('\'\"\\test'); select quote(concat('abc\'', '\\cba')); select quote(1/0), quote('\0\Z'); select length(quote(concat(char(0),"test"))); +select hex(quote(concat(char(224),char(227),char(230),char(231),char(232),char(234),char(235)))); # # Wrong usage of functions diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index deb3358da00..99824ab121d 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -201,3 +201,10 @@ select * from t1, t2 where t1.start between t2.ctime1 and t2.ctime2; select * from t1, t2 where t1.start >= t2.ctime1 and t1.start <= t2.ctime2; select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2; drop table t1,t2,t3; + +# +# Test unix timestamp +# +select @a:=FROM_UNIXTIME(1); +select unix_timestamp(@a); +select unix_timestamp('1969-12-01 19:00:01'); diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index ea9c5e0cf55..7cc509caf74 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -857,3 +857,15 @@ insert into t2 select * from t1; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; drop table t1,t2; + +# +# test autoincrement with TRUNCATE +# + +SET AUTOCOMMIT=1; +create table t1 (a integer auto_increment primary key) type=innodb; +insert into t1 (a) values (NULL),(NULL); +truncate table t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +drop table t1; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 7aa4e74cec0..df1174ce9af 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -267,3 +267,13 @@ insert into t2 values (1,1), (3,1); update t1 left join t2 on t1.a=t2.a set t1.b=2, t2.b=2 where t1.b=1 and t2.b=1 or t2.a is NULL; select t1.a, t1.b,t2.a, t2.b from t1 left join t2 on t1.a=t2.a where t1.b=1 and t2.b=1 or t2.a is NULL; drop table t1,t2; + +# +# Test reuse of same table +# + +create table t1 (a int not null auto_increment primary key, b int not null); +insert into t1 (b) values (1),(2),(3),(4); +update t1, t1 as t2 set t1.b=t2.b+1 where t1.a=t2.a; +select * from t1; +drop table t1; diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 5e1fe313a7e..7a42a60054e 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -90,3 +90,25 @@ select count(*) from mysqltest.t9; --replace_result $MYSQL_TEST_DIR TEST_DIR show create table mysqltest.t9; drop database mysqltest; + +# +# Test changing data dir (Bug #1662) +# + +create table t1 (a int not null) type=myisam; +disable_query_log; +eval alter table t1 data directory="$MYSQL_TEST_DIR/var/tmp"; +enable_query_log; +--replace_result $MYSQL_TEST_DIR TEST_DIR +show create table t1; +alter table t1 add b int; +disable_query_log; +eval alter table t1 data directory="$MYSQL_TEST_DIR/var/log"; +enable_query_log; +--replace_result $MYSQL_TEST_DIR TEST_DIR +show create table t1; +disable_query_log; +eval alter table t1 index directory="$MYSQL_TEST_DIR/var/log"; +enable_query_log; +show create table t1; +drop table t1; diff --git a/mysql-test/t/timezone.test b/mysql-test/t/timezone.test index 14facc0374a..d9603c51766 100644 --- a/mysql-test/t/timezone.test +++ b/mysql-test/t/timezone.test @@ -1,7 +1,7 @@ # -# Test of timezone handling. This script must be run with TZ=MEST +# Test of timezone handling. This script must be run with TZ=MET --- require r/have_mest_timezone.require +-- require r/have_met_timezone.require disable_query_log; show variables like "timezone"; enable_query_log; @@ -26,3 +26,9 @@ INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 04:00:01')); SELECT ts,from_unixtime(ts) FROM t1; DROP TABLE t1; + +# +# Test unix timestamp +# +select @a:=FROM_UNIXTIME(1); +select unix_timestamp(@a); diff --git a/mysql-test/t/truncate.test b/mysql-test/t/truncate.test index eeb79f497fa..3acab9f56de 100644 --- a/mysql-test/t/truncate.test +++ b/mysql-test/t/truncate.test @@ -21,3 +21,15 @@ select * from t1; drop table t1; --error 1146 truncate non_existing_table; + +# +# test autoincrement with TRUNCATE +# + +create table t1 (a integer auto_increment primary key); +insert into t1 (a) values (NULL),(NULL); +truncate table t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +drop table t1; + diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 4132b1f48a4..cf5c0d6e581 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -263,3 +263,52 @@ insert into t1 (id) values (1); update t1 set imagem=load_file('../../std_data/words.dat') where id=1; select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1; drop table t1; + +# +# Test blob's with end space (Bug #1651) +# + +create table t1 (id integer primary key auto_increment, txt text not null, unique index txt_index (txt (20))); +insert into t1 (txt) values ('Chevy'), ('Chevy '); +select * from t1 where txt='Chevy'; +select * from t1 where txt='Chevy '; +select * from t1 where txt='Chevy ' or txt='Chevy'; +select * from t1 where txt='Chevy' or txt='Chevy '; +select * from t1 where id='1' or id='2'; +insert into t1 (txt) values('Ford'); +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford'; +select * from t1 where txt='Chevy' or txt='Chevy '; +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy'; +select * from t1 where txt in ('Chevy ','Chevy'); +select * from t1 where txt in ('Chevy'); +select * from t1 where txt between 'Chevy' and 'Chevy'; +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy '; +select * from t1 where txt between 'Chevy' and 'Chevy '; +select * from t1 where txt < 'Chevy '; +select * from t1 where txt <= 'Chevy'; +select * from t1 where txt > 'Chevy'; +select * from t1 where txt >= 'Chevy'; +drop table t1; + +create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20))); +insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); +select * from t1 where txt='Chevy' or txt is NULL; +select * from t1 where txt='Chevy '; +select * from t1 where txt='Chevy ' or txt='Chevy'; +select * from t1 where txt='Chevy' or txt='Chevy '; +select * from t1 where id='1' or id='2'; +insert into t1 (txt) values('Ford'); +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford'; +select * from t1 where txt='Chevy' or txt='Chevy '; +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy'; +select * from t1 where txt in ('Chevy ','Chevy'); +select * from t1 where txt in ('Chevy'); +select * from t1 where txt between 'Chevy' and 'Chevy'; +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy '; +select * from t1 where txt between 'Chevy' and 'Chevy '; +select * from t1 where txt < 'Chevy '; +select * from t1 where txt < 'Chevy ' or txt is NULL; +select * from t1 where txt <= 'Chevy'; +select * from t1 where txt > 'Chevy'; +select * from t1 where txt >= 'Chevy'; +drop table t1; diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c index 68b034bec5c..913f632fbb4 100644 --- a/mysys/my_symlink2.c +++ b/mysys/my_symlink2.c @@ -31,9 +31,19 @@ File my_create_with_symlink(const char *linkname, const char *filename, File file; int tmp_errno; /* Test if we should create a link */ - int create_link=(linkname && strcmp(linkname,filename)); + int create_link; DBUG_ENTER("my_create_with_symlink"); + if (my_disable_symlinks) + { + /* Create only the file, not the link and file */ + create_link= 0; + if (linkname) + filename= linkname; + } + else + create_link= (linkname && strcmp(linkname,filename)); + if (!(MyFlags & MY_DELETE_OLD)) { if (!access(filename,F_OK)) diff --git a/sql/field.h b/sql/field.h index 3186f9f5275..8a829a455ed 100644 --- a/sql/field.h +++ b/sql/field.h @@ -799,9 +799,10 @@ public: binary_flag(binary_arg) { if (binary_arg) - flags|=BINARY_FLAG; + flags|= BINARY_FLAG; } - Field_varstring(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, + Field_varstring(uint32 len_arg,bool maybe_null_arg, + const char *field_name_arg, struct st_table *table_arg, bool binary_arg) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, table_arg), @@ -856,7 +857,7 @@ public: { flags|= BLOB_FLAG; if (binary_arg) - flags|=BINARY_FLAG; + flags|= BINARY_FLAG; } enum_field_types type() const { return FIELD_TYPE_BLOB;} enum ha_base_keytype key_type() const diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 47c49b79d77..beff8c1f515 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1788,7 +1788,7 @@ ha_innobase::store_key_val_for_row( || mysql_type == FIELD_TYPE_BLOB || mysql_type == FIELD_TYPE_LONG_BLOB) { - ut_a(key_part->key_part_flag & HA_PART_KEY); + ut_a(key_part->key_part_flag & HA_PART_KEY_SEG); if (is_null) { buff += key_part->length + 2; @@ -3270,7 +3270,7 @@ create_index( for (i = 0; i < n_fields; i++) { key_part = key->key_part + i; - /* (The flag HA_PART_KEY denotes in MySQL a column prefix + /* (The flag HA_PART_KEY_SEG denotes in MySQL a column prefix field in an index: we only store a specified number of first bytes of the column to the index field.) The flag does not seem to be properly set by MySQL. Let us fall back on testing diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 7434f6bd57b..a4d04253dd7 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2169,7 +2169,7 @@ String *Item_func_quote::val_str(String *str) new_length= arg_length+2; /* for beginning and ending ' signs */ for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++) - new_length+= get_esc_bit(escmask, *from); + new_length+= get_esc_bit(escmask, (uchar) *from); /* We have to use realloc() instead of alloc() as we want to keep the diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 04529919990..d0e0e6992fa 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -364,6 +364,7 @@ void mysql_execute_command(void); bool do_command(THD *thd); bool dispatch_command(enum enum_server_command command, THD *thd, char* packet, uint packet_length); +bool check_dup(const char *db, const char *name, TABLE_LIST *tables); #ifndef EMBEDDED_LIBRARY bool check_stack_overrun(THD *thd,char *dummy); #else diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 02b7699fad6..74fa237fd73 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -942,9 +942,10 @@ static SEL_ARG * get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, Item_func::Functype type,Item *value) { - uint maybe_null=(uint) field->real_maybe_null(); + uint maybe_null=(uint) field->real_maybe_null(), copies; uint field_length=field->pack_length()+maybe_null; SEL_ARG *tree; + char *str, *str2; DBUG_ENTER("get_mm_leaf"); if (type == Item_func::LIKE_FUNC) @@ -1056,15 +1057,39 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, /* This happens when we try to insert a NULL field in a not null column */ DBUG_RETURN(&null_element); // cmp with NULL is never true } - // Get local copy of key - char *str= (char*) alloc_root(param->mem_root, - key_part->part_length+maybe_null); + /* Get local copy of key */ + copies= 1; + if (field->key_type() == HA_KEYTYPE_VARTEXT) + copies= 2; + str= str2= (char*) alloc_root(param->mem_root, + (key_part->part_length+maybe_null)*copies); if (!str) DBUG_RETURN(0); if (maybe_null) *str= (char) field->is_real_null(); // Set to 1 if null field->get_key_image(str+maybe_null,key_part->part_length); - if (!(tree=new SEL_ARG(field,str,str))) + if (copies == 2) + { + /* + The key is stored as 2 byte length + key + key doesn't match end space. In other words, a key 'X ' should match + all rows between 'X' and 'X ...' + */ + uint length= uint2korr(str+maybe_null); + char *end; + str2= str+ key_part->part_length + maybe_null; + /* remove end space. The 2 is for the packed length */ + while (length > 0 && str[length+2+maybe_null-1] == ' ') + length--; + int2store(str+maybe_null, length); + /* Create key that is space filled */ + memcpy(str2, str, length+2+maybe_null); + end= str2+ maybe_null + key_part->part_length; + for (char *pos= str2+ 2+ length + maybe_null; pos < end ; pos++) + *pos++= ' '; + int2store(str2+maybe_null, key_part->part_length); + } + if (!(tree=new SEL_ARG(field,str,str2))) DBUG_RETURN(0); // out of memory switch (type) { @@ -2233,7 +2258,8 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, param->range_count++; if (!tmp_min_flag && ! tmp_max_flag && (uint) key_tree->part+1 == param->table->key_info[keynr].key_parts && - (param->table->key_info[keynr].flags & HA_NOSAME) && + (param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) == + HA_NOSAME && min_key_length == max_key_length && !memcmp(param->min_key,param->max_key,min_key_length)) tmp=1; // Max one record @@ -2367,7 +2393,8 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key, { KEY *table_key=quick->head->key_info+quick->index; flag=EQ_RANGE; - if (table_key->flags & HA_NOSAME && key->part == table_key->key_parts-1) + if ((table_key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME && + key->part == table_key->key_parts-1) { if (!(table_key->flags & HA_NULL_PART_KEY) || !null_part_in_key(key, @@ -2412,7 +2439,7 @@ bool QUICK_SELECT::unique_key_range() if (((tmp=ranges.head())->flag & (EQ_RANGE | NULL_RANGE)) == EQ_RANGE) { KEY *key=head->key_info+index; - return ((key->flags & HA_NOSAME) && + return ((key->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME && key->key_length == tmp->min_length); } } @@ -2465,7 +2492,8 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) range->min_key=range->max_key=(char*) ref->key_buff; range->min_length=range->max_length=ref->key_length; range->flag= ((ref->key_length == key_info->key_length && - (key_info->flags & HA_NOSAME)) ? EQ_RANGE : 0); + (key_info->flags & (HA_NOSAME | HA_END_SPACE_KEY)) == + HA_NOSAME) ? EQ_RANGE : 0); if (!(quick->key_parts=key_part=(KEY_PART *) alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts))) diff --git a/sql/records.cc b/sql/records.cc index fd46506203f..415e75a467b 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -99,11 +99,12 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, info->read_record=rr_sequential; table->file->rnd_init(); /* We can use record cache if we don't update dynamic length tables */ - if (use_record_cache > 0 || - (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY || - !(table->db_options_in_use & HA_OPTION_PACK_RECORD) || - (use_record_cache < 0 && - !(table->file->table_flags() & HA_NOT_DELETE_WITH_CACHE))) + if (!table->no_cache && + (use_record_cache > 0 || + (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY || + !(table->db_options_in_use & HA_OPTION_PACK_RECORD) || + (use_record_cache < 0 && + !(table->file->table_flags() & HA_NOT_DELETE_WITH_CACHE)))) VOID(table->file->extra_opt(HA_EXTRA_CACHE, thd->variables.read_buff_size)); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 03a359d44e7..a395396be2d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1202,11 +1202,11 @@ static const char *calc_ip(const char *ip, long *val, char end) static void update_hostname(acl_host_and_ip *host, const char *hostname) { host->hostname=(char*) hostname; // This will not be modified! - if (hostname && + if (!hostname || (!(hostname=calc_ip(hostname,&host->ip,'/')) || !(hostname=calc_ip(hostname+1,&host->ip_mask,'\0')))) { - host->ip=host->ip_mask=0; // Not a masked ip + host->ip= host->ip_mask=0; // Not a masked ip } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d59dda43d67..01d6500260f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -56,7 +56,6 @@ static int check_for_max_user_connections(USER_CONN *uc); static void decrease_user_connections(USER_CONN *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); -static bool check_dup(const char *db, const char *name, TABLE_LIST *tables); static void mysql_init_query(THD *thd); static void remove_escape(char *name); static void refresh_status(void); @@ -3600,7 +3599,7 @@ void add_join_natural(TABLE_LIST *a,TABLE_LIST *b) /* Check if name is used in table list */ -static bool check_dup(const char *db, const char *name, TABLE_LIST *tables) +bool check_dup(const char *db, const char *name, TABLE_LIST *tables) { for (; tables ; tables=tables->next) if (!strcmp(name,tables->real_name) && !strcmp(db,tables->db)) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 892ad02bb5b..22864dedc49 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1261,7 +1261,8 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, } while (keyuse->table == table && keyuse->key == key); if (eq_part == PREV_BITS(uint,table->key_info[key].key_parts) && - (table->key_info[key].flags & HA_NOSAME) && + ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) == + HA_NOSAME) && !table->fulltext_searched) { if (const_ref == eq_part) @@ -2020,7 +2021,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, if (found_part == PREV_BITS(uint,keyinfo->key_parts)) { /* use eq key */ max_key_part= (uint) ~0; - if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) + if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY | + HA_END_SPACE_KEY)) == HA_NOSAME) { tmp=prev_record_reads(join,found_ref); records=1.0; @@ -2520,8 +2522,8 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, if (j->type == JT_FT) /* no-op */; else if (j->type == JT_CONST) j->table->const_table=1; - else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) - != HA_NOSAME) || + else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY | + HA_END_SPACE_KEY)) != HA_NOSAME) || keyparts != keyinfo->key_parts) j->type=JT_REF; /* Must read with repeat */ else if (ref_key == j->ref.key_copy) @@ -5814,7 +5816,7 @@ part_of_refkey(TABLE *table,Field *field) for (uint part=0 ; part < ref_parts ; part++,key_part++) if (field->eq(key_part->field) && - !(key_part->key_part_flag & HA_PART_KEY)) + !(key_part->key_part_flag & HA_PART_KEY_SEG)) return table->reginfo.join_tab->ref.items[part]; } return (Item*) 0; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 94ecf33b9c6..d827d8c403c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -288,10 +288,10 @@ static int sort_keys(KEY *a, KEY *b) { if (!(b->flags & HA_NOSAME)) return -1; - if ((a->flags ^ b->flags) & HA_NULL_PART_KEY) + if ((a->flags ^ b->flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) { /* Sort NOT NULL keys before other keys */ - return (a->flags & HA_NULL_PART_KEY) ? 1 : -1; + return (a->flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1; } if (a->name == primary_key_name) return -1; @@ -1695,8 +1695,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } /* - ** Collect all keys which isn't in drop list. Add only those - ** for which some fields exists. + Collect all keys which isn't in drop list. Add only those + for which some fields exists. */ List_iterator key_it(keys); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d5034644830..af5c48fdb87 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -544,6 +544,26 @@ int multi_update::prepare(List ¬_used_values) for (i=0 ; i < table_count ; i++) set_if_bigger(max_fields, fields_for_table[i]->elements); copy_field= new Copy_field[max_fields]; + + /* + Mark all copies of tables that are updates to ensure that + init_read_record() will not try to enable a cache on them + + The problem is that for queries like + + UPDATE t1, t1 AS t2 SET t1.b=t2.c WHERE t1.a=t2.a; + + the row buffer may contain things that doesn't match what is on disk + which will cause an error when reading a row. + (This issue is mostly relevent for MyISAM tables) + */ + for (table_ref= all_tables; table_ref; table_ref=table_ref->next) + { + TABLE *table=table_ref->table; + if (!(tables_to_update & table->map) && + check_dup(table_ref->db, table_ref->real_name, update_tables)) + table->no_cache= 1; // Disable row cache + } DBUG_RETURN(thd->fatal_error != 0); } @@ -684,7 +704,7 @@ multi_update::~multi_update() { TABLE_LIST *table; for (table= update_tables ; table; table= table->next) - table->table->no_keyread=0; + table->table->no_keyread= table->table->no_cache= 0; if (tmp_tables) { diff --git a/sql/table.cc b/sql/table.cc index 0789f7469e7..c8def7441fd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -430,14 +430,17 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME)) { /* - If the UNIQUE key don't have NULL columns, declare this as - a primary key. + If the UNIQUE key doesn't have NULL columns and is not a part key + declare this as a primary key. */ primary_key=key; for (i=0 ; i < keyinfo->key_parts ;i++) { - if (!key_part[i].fieldnr || - outparam->field[key_part[i].fieldnr-1]->null_ptr) + uint fieldnr= key_part[i].fieldnr; + if (!fieldnr || + outparam->field[fieldnr-1]->null_ptr || + outparam->field[fieldnr-1]->key_length() != + key_part[i].length) { primary_key=MAX_KEY; // Can't be used break; @@ -476,6 +479,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, keyinfo->extra_length+=HA_KEY_BLOB_LENGTH; key_part->store_length+=HA_KEY_BLOB_LENGTH; keyinfo->key_length+= HA_KEY_BLOB_LENGTH; + /* + Mark that there may be many matching values for one key + combination ('a', 'a ', 'a '...) + */ + if (!(field->flags & BINARY_FLAG)) + keyinfo->flags|= HA_END_SPACE_KEY; } if (i == 0 && key != primary_key) field->flags |= @@ -513,7 +522,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, } if (field->key_length() != key_part->length) { - key_part->key_part_flag|= HA_PART_KEY; + key_part->key_part_flag|= HA_PART_KEY_SEG; if (field->type() != FIELD_TYPE_BLOB) { // Create a new field field=key_part->field=field->new_field(&outparam->mem_root, @@ -527,7 +536,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, as we need to test for NULL = NULL. */ if (field->real_maybe_null()) - key_part->key_part_flag|= HA_PART_KEY; + key_part->key_part_flag|= HA_PART_KEY_SEG; } else { // Error: shorten key diff --git a/sql/table.h b/sql/table.h index 57be97ffbda..f3b0e148cc0 100644 --- a/sql/table.h +++ b/sql/table.h @@ -101,7 +101,7 @@ struct st_table { my_bool fulltext_searched; my_bool crashed; my_bool is_view; - my_bool no_keyread; + my_bool no_keyread, no_cache; Field *next_number_field, /* Set if next_number is activated */ *found_next_number_field, /* Set on open */ *rowid_field; diff --git a/sql/time.cc b/sql/time.cc index bf218fa58ab..5dc229b1d88 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -125,6 +125,8 @@ long my_gmt_sec(TIME *t, long *my_timezone) tmp-=t->minute*60 + t->second; // Move to previous hour } *my_timezone= current_timezone; + if (tmp < 0 && t->year <= 1900+YY_PART_YEAR) + tmp= 0; return (long) tmp; } /* my_gmt_sec */ @@ -445,7 +447,7 @@ time_t str_to_timestamp(const char *str,uint length) if (str_to_TIME(str,length,&l_time,0) == TIMESTAMP_NONE) return(0); - if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR) + if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR-1) { current_thd->cuted_fields++; return(0); From 15e70c5480b1a6b6f6cad18e2e4438998d18a3ac Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Fri, 12 Dec 2003 13:14:59 -0800 Subject: [PATCH 57/89] sql_delete.cc, sql_update.cc, sql_class.h: Simplification of the previous fix for multi-update/delete. --- sql/sql_class.h | 4 +--- sql/sql_delete.cc | 11 +++++------ sql/sql_update.cc | 5 ++--- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index c487e212e24..0d0e0d7fbc5 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -844,11 +844,10 @@ class multi_delete : public select_result TABLE_LIST *delete_tables, *table_being_deleted; Unique **tempfiles; THD *thd; - ha_rows deleted; + ha_rows deleted, found; uint num_of_tables; int error; bool do_delete, transactional_tables, log_delayed, normal_tables; - bool tempfiles_inited; public: multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables); @@ -876,7 +875,6 @@ class multi_update : public select_result Copy_field *copy_field; enum enum_duplicates handle_duplicates; bool do_update, trans_safe, transactional_tables, log_delayed; - bool tmp_tables_inited; public: multi_update(THD *thd_arg, TABLE_LIST *ut, List *fields, diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 399f237bf2f..bdf2cf85749 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -234,10 +234,9 @@ extern "C" int refposcmp2(void* arg, const void *a,const void *b) multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, uint num_of_tables_arg) - : delete_tables(dt), thd(thd_arg), deleted(0), + : delete_tables(dt), thd(thd_arg), deleted(0), found(0), num_of_tables(num_of_tables_arg), error(0), - do_delete(0), transactional_tables(0), log_delayed(0), normal_tables(0), - tempfiles_inited(0) + do_delete(0), transactional_tables(0), log_delayed(0), normal_tables(0) { tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1)); } @@ -298,7 +297,6 @@ multi_delete::initialize_tables(JOIN *join) table->file->ref_length, MEM_STRIP_BUF_SIZE); } - tempfiles_inited= 1; init_ftfuncs(thd,1); DBUG_RETURN(thd->fatal_error != 0); } @@ -339,6 +337,7 @@ bool multi_delete::send_data(List &values) continue; table->file->position(table->record[0]); + found++; if (secure_counter < 0) { @@ -414,7 +413,7 @@ int multi_delete::do_deletes(bool from_send_error) if (from_send_error) { - /* Found out table number for 'table_being_deleted' */ + /* Found out table number for 'table_being_deleted*/ for (TABLE_LIST *aux=delete_tables; aux != table_being_deleted; aux=aux->next) @@ -424,7 +423,7 @@ int multi_delete::do_deletes(bool from_send_error) table_being_deleted = delete_tables; do_delete= 0; - if (!tempfiles_inited) + if (!found) DBUG_RETURN(0); for (table_being_deleted=table_being_deleted->next; table_being_deleted ; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 19df0661db3..959abcae39c 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -440,7 +440,7 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, :all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0), updated(0), found(0), fields(field_list), values(value_list), table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg), - do_update(1), trans_safe(0), tmp_tables_inited(0) + do_update(1), trans_safe(0) {} @@ -622,7 +622,6 @@ multi_update::initialize_tables(JOIN *join) DBUG_RETURN(1); tmp_tables[cnt]->file->extra(HA_EXTRA_WRITE_CACHE); } - tmp_tables_inited= 1; DBUG_RETURN(0); } @@ -823,7 +822,7 @@ int multi_update::do_updates(bool from_send_error) do_update= 0; // Don't retry this function - if (!tmp_tables_inited) + if (!found) DBUG_RETURN(0); for (cur_table= update_tables; cur_table ; cur_table= cur_table->next) { From 700de3ebec93a4f1ac60bee34eee331f8f5db5b1 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Fri, 12 Dec 2003 17:18:48 -0400 Subject: [PATCH 58/89] changed %ld on %lu for output of mysql_thread_id(&mysql) as is thread_id has type ulong (bug #1951 thread id is printed as "signed" instead of "unsigned" in 'mysql') --- client/mysql.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index fd63c0dc18e..083e8fd6ac3 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -358,7 +358,7 @@ int main(int argc,char *argv[]) put_info("Welcome to the MySQL monitor. Commands end with ; or \\g.", INFO_INFO); sprintf((char*) glob_buffer.ptr(), - "Your MySQL connection id is %ld to server version: %s\n", + "Your MySQL connection id is %lu to server version: %s\n", mysql_thread_id(&mysql),mysql_get_server_info(&mysql)); put_info((char*) glob_buffer.ptr(),INFO_INFO); @@ -1359,7 +1359,7 @@ com_help (String *buffer __attribute__((unused)), } if (connected) tee_fprintf(stdout, - "\nConnection id: %ld (Can be used with mysqladmin kill)\n\n", + "\nConnection id: %lu (Can be used with mysqladmin kill)\n\n", mysql_thread_id(&mysql)); else tee_fprintf(stdout, "Not connected! Reconnect with 'connect'!\n\n"); @@ -2109,7 +2109,7 @@ com_connect(String *buffer, char *line) if (connected) { - sprintf(buff,"Connection id: %ld",mysql_thread_id(&mysql)); + sprintf(buff,"Connection id: %lu",mysql_thread_id(&mysql)); put_info(buff,INFO_INFO); sprintf(buff,"Current database: %s\n", current_db ? current_db : "*** NONE ***"); @@ -2323,7 +2323,7 @@ com_status(String *buffer __attribute__((unused)), { MYSQL_RES *result; LINT_INIT(result); - tee_fprintf(stdout, "\nConnection id:\t\t%ld\n",mysql_thread_id(&mysql)); + tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql)); if (!mysql_query(&mysql,"select DATABASE(),USER()") && (result=mysql_use_result(&mysql))) { From 6876df424c7cec283d3ee96e8fc03a72cb0b1cc5 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Fri, 12 Dec 2003 23:06:26 +0100 Subject: [PATCH 59/89] - Reworked the Do-rpm build script to be more flexible - Reworked testing for gcc3 in the RPM spec file a bit --- Build-tools/Do-rpm | 85 +++++++++++++++++++++++++------------ support-files/mysql.spec.sh | 6 ++- 2 files changed, 63 insertions(+), 28 deletions(-) diff --git a/Build-tools/Do-rpm b/Build-tools/Do-rpm index 0f423feb921..cedd55d1405 100755 --- a/Build-tools/Do-rpm +++ b/Build-tools/Do-rpm @@ -3,14 +3,12 @@ # Do-rpm - compile RPM packages out of a source tarball and move the # resulting RPM packages into the current directory. # -# The script currently assumes the following environment (which should exist -# like that, if the Do-compile script was used to build the binary -# distribution) +# The script currently assumes the following environment: # # - there must be a source distribution (mysql-.tar.gz) # in the current directory -# - there must be a spec file (mysql-.spec) in the directory -# $HOME//mysql-/support-files/ +# - You must provide the name of an RPM spec file (mysql-.spec) +# as the argument # # Use the "--help" option for more info! # @@ -35,7 +33,10 @@ $opt_log= undef; $opt_mail= ""; $opt_verbose= undef; +# Set a dummy version until we know the correct one +$VERSION= "x.y.z"; $MAJOR= $MINOR= $RELEASE= 0; +$SUFFIX= ""; GetOptions( "cc=s", @@ -50,7 +51,9 @@ GetOptions( "verbose|v", ) || &print_help; -defined($VERSION=$ARGV[0]) || print_help("Please provide the MySQL version!"); +&print_help("") if ($opt_help); + +defined($SPECFILE=$ARGV[0]) || print_help("Please provide the spec file name!"); # Include helper functions $PWD= cwd(); @@ -64,6 +67,28 @@ else die "ERROR: $LOGGER cannot be found!\n"; } +# Open the spec file and extract the version number +open(SPEC, $SPECFILE) or &abort("Unable to open \"$ARGV[0]\": $!"); +@spec= ; +close SPEC; + +foreach (@spec) +{ + if (m/^%define\s*mysql_version\s*(.*)/) + { + $VERSION= $1; + ($MAJOR, $MINOR, $RELEASE)= split(/\./,$VERSION); + ($RELEASE, $SUFFIX)= split(/\-/,$RELEASE); + $SUFFIX= "-" . $SUFFIX if ($SUFFIX); + } +} + +$HOST= hostname(); +$HOST=~ /^([^.-]*)/; +$HOST= $1; +$LOGFILE= "$PWD/Logs/Do-rpm-$HOST-$MAJOR.$MINOR.log"; +&logger("Using spec file for version: $VERSION"); + # # Override predefined Log file name # @@ -82,14 +107,6 @@ if (defined $opt_log) } } -($MAJOR, $MINOR, $RELEASE)= split(/\./, $VERSION); -$HOST= hostname(); -$HOST=~ /^([^.-]*)/; -$HOST= $1; -$LOGFILE= "$PWD/Logs/Do-rpm-$HOST-$MAJOR.$MINOR.log"; - -&print_help("") if ($opt_help); - # # Newer RPM versions ship with a separate tool "rpmbuild" to build RPMs # @@ -120,8 +137,7 @@ chomp($SOURCEDIR= `$RPM --eval "%{_sourcedir}" 2> /dev/null`); chomp($SPECDIR= `$RPM --eval "%{_specdir}" 2> /dev/null`); chomp($SRCRPMDIR= `$RPM --eval "%{_srcrpmdir}" 2> /dev/null`); -$SOURCEFILE= "mysql-$VERSION.tar.gz"; -$SPECFILE= "$PWD/$HOST/mysql-$VERSION/support-files/mysql-$VERSION.spec"; +$SOURCEFILE= glob "mysql*-$VERSION.tar.gz"; &logger("Starting RPM build of MySQL-$VERSION on $HOST"); @@ -134,10 +150,13 @@ foreach $file ($SOURCEFILE, $SPECFILE) # Install source and spec file # &logger("Copying SOURCE and SPEC file to build directories."); -copy($SOURCEFILE, $SOURCEDIR) -or &abort("Unable to copy $SOURCEFILE to $SOURCEDIR!"); -copy($SPECFILE, $SPECDIR) -or &abort("Unable to copy $SPECFILE to $SPECDIR!"); +unless ($opt_dry_run) +{ + copy($SOURCEFILE, $SOURCEDIR) + or &abort("Unable to copy $SOURCEFILE to $SOURCEDIR!"); + copy($SPECFILE, $SPECDIR) + or &abort("Unable to copy $SPECFILE to $SPECDIR!"); +} # # Set environment variables - these are being used in the @@ -168,11 +187,13 @@ $command.= basename($SPECFILE); $command= "mv"; $command.= " -v " if ($opt_verbose); $command.= "$SRCRPMDIR/MySQL*$VERSION*.src.rpm $PWD"; +&logger("Moving source RPM to current dir."); &run_command($command, "Error moving source RPM!"); $command= "mv"; $command.= " -v " if ($opt_verbose); $command.= "$RPMDIR/$RPMARCH/MySQL*$VERSION*.$RPMARCH.rpm $PWD"; +&logger("Moving binary RPMs to current dir."); &run_command($command, "Error moving binary RPMs!"); # @@ -181,11 +202,14 @@ $command.= "$RPMDIR/$RPMARCH/MySQL*$VERSION*.$RPMARCH.rpm $PWD"; if ($opt_clean) { &logger("Removing spec file and source package"); - unlink("$SPECDIR/" . basename($SPECFILE)); - unlink("$SOURCEDIR/$SOURCEFILE"); + unless ($opt_dry_run) + { + unlink("$SPECDIR/" . basename($SPECFILE)); + unlink("$SOURCEDIR/$SOURCEFILE"); + } } -&logger("SUCCESS: RPM files successfully created.") if (!$opt_dry_run); +&logger("SUCCESS: RPM files successfully created.") unless ($opt_dry_run); exit 0; sub print_help @@ -198,11 +222,14 @@ sub print_help } print < +Usage: Do-rpm [options] -Creates a binary RPM package out of a MySQL source distribution and moves the -resulting RPMs into the current directory. is the MySQL version -number (e.g. 4.0.11-gamma) +Creates a binary RPM package out of a MySQL source distribution and moves +the resulting RPMs into the current directory. is the MySQL RPM +spec file to use (e.g. mysql-4.0.17.spec). + +This script expects to find the required MySQL source distribution +(mysql-.tar.gz) in the current directory. Options: @@ -222,6 +249,10 @@ Options: Example: --mail=user\\\@domain.com -v, --verbose Verbose execution +Example: + + Do-rpm -cv mysql-4.0.17.spec + EOF exit 1; } diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 658b90d1a3f..1cb25e2ff42 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -260,7 +260,7 @@ export PATH # If we want to compile with RAID using gcc 3, we need to use # gcc instead of g++ to avoid linking problems (RAID code is written in C++) -if gcc -v 2>&1 | grep 'version 3' > /dev/null 2>&1 +test -z $CXX && test -z $CC && if gcc -v 2>&1 | grep 'gcc version 3' > /dev/null 2>&1 then export CXX="gcc" fi @@ -567,6 +567,10 @@ fi # The spec file changelog only includes changes made to the spec file # itself %changelog +* Thu Dec 11 2003 Lenz Grimmer + +- made testing for gcc3 a bit more robust + * Fri Nov 21 2003 Lenz Grimmer - removed dependency on MySQL-client from the MySQL-devel subpackage From 6d9aca5069bd046c3fc63bee02e60a6d1cdacf86 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sat, 13 Dec 2003 01:31:59 +0200 Subject: [PATCH 60/89] btr0cur.c, row0umod.c: Fix bug: if one updated a secondary index column so that its alphabetical value did not change (e.g., abc -> aBc) and rolled back the update, InnoDB failed to return the value in the secondary index to its original value row0upd.h: Correct typing error sync0sync.ic: Remove inadvertently pushed sync debug code --- innobase/btr/btr0cur.c | 3 +- innobase/include/row0upd.h | 2 +- innobase/include/sync0sync.ic | 2 - innobase/row/row0umod.c | 124 +++++++++++++++++++++++++++++----- 4 files changed, 109 insertions(+), 22 deletions(-) diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index bd09895656c..bfb4d042850 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -1175,7 +1175,8 @@ btr_cur_upd_lock_and_undo( if (!(index->type & DICT_CLUSTERED)) { /* We do undo logging only when we update a clustered index record */ - return(lock_sec_rec_modify_check_and_lock(0, rec, index, thr)); + return(lock_sec_rec_modify_check_and_lock(flags, rec, index, + thr)); } /* Check if we have to wait for a lock: enqueue an explicit lock diff --git a/innobase/include/row0upd.h b/innobase/include/row0upd.h index dd989982743..f5e0a88231f 100644 --- a/innobase/include/row0upd.h +++ b/innobase/include/row0upd.h @@ -292,7 +292,7 @@ row_upd_index_parse( /* Update vector field */ struct upd_field_struct{ ulint field_no; /* field number in an index, usually - the clustered index, but in upadating + the clustered index, but in updating a secondary index record in btr0cur.c this is the position in the secondary index */ diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic index a9b511a7593..c11cc0d196e 100644 --- a/innobase/include/sync0sync.ic +++ b/innobase/include/sync0sync.ic @@ -257,8 +257,6 @@ mutex_enter_func( mutex->file_name = file_name; mutex->line = line; - mutex->thread_id = os_thread_get_curr_id(); - return; /* Succeeded! */ } diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index b22e494f891..34c3aaf9142 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -377,8 +377,14 @@ row_undo_mod_del_mark_or_remove_sec_low( } /*************************************************************** -Delete marks or removes a secondary index entry if found. */ -UNIV_INLINE +Delete marks or removes a secondary index entry if found. +NOTE that if we updated the fields of a delete-marked secondary index record +so that alphabetically they stayed the same, e.g., 'abc' -> 'aBc', we cannot +return to the original values because we do not know them. But this should +not cause problems because in row0sel.c, in queries we always retrieve the +clustered index record or an earlier version of it, if the secondary index +record through which we do the search is delete-marked. */ +static ulint row_undo_mod_del_mark_or_remove_sec( /*================================*/ @@ -403,20 +409,31 @@ row_undo_mod_del_mark_or_remove_sec( } /*************************************************************** -Delete unmarks a secondary index entry which must be found. */ +Delete unmarks a secondary index entry which must be found. It might not be +delete-marked at the moment, but it does not harm to unmark it anyway. We also +need to update the fields of the secondary index record if we updated its +fields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'. */ static -void -row_undo_mod_del_unmark_sec( -/*========================*/ +ulint +row_undo_mod_del_unmark_sec_and_undo_update( +/*========================================*/ + /* out: DB_FAIL or DB_SUCCESS or + DB_OUT_OF_FILE_SPACE */ + ulint mode, /* in: search mode: BTR_MODIFY_LEAF or + BTR_MODIFY_TREE */ undo_node_t* node, /* in: row undo node */ que_thr_t* thr, /* in: query thread */ dict_index_t* index, /* in: index */ dtuple_t* entry) /* in: index entry */ { + mem_heap_t* heap; btr_pcur_t pcur; btr_cur_t* btr_cur; - ulint err; + upd_t* update; + rec_t* rec; + ulint err = DB_SUCCESS; ibool found; + big_rec_t* dummy_big_rec; mtr_t mtr; char err_buf[1000]; @@ -425,8 +442,8 @@ row_undo_mod_del_unmark_sec( log_free_check(); mtr_start(&mtr); - found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur, - &mtr); + found = row_search_index_entry(index, entry, mode, &pcur, &mtr); + if (!found) { fprintf(stderr, "InnoDB: error in sec index entry del undo in\n" @@ -443,17 +460,47 @@ row_undo_mod_del_unmark_sec( "%s\nInnoDB: Make a detailed bug report and send it\n", err_buf); fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); - } else { btr_cur = btr_pcur_get_btr_cur(&pcur); + rec = btr_cur_get_rec(btr_cur); + err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG, btr_cur, FALSE, thr, &mtr); - ut_ad(err == DB_SUCCESS); + ut_a(err == DB_SUCCESS); + heap = mem_heap_create(100); + + update = row_upd_build_sec_rec_difference_binary(index, entry, + rec, heap); + if (upd_get_n_fields(update) == 0) { + + /* Do nothing */ + + } else if (mode == BTR_MODIFY_LEAF) { + /* Try an optimistic updating of the record, keeping + changes within the page */ + + err = btr_cur_optimistic_update(BTR_KEEP_SYS_FLAG + | BTR_NO_LOCKING_FLAG, + btr_cur, update, 0, thr, &mtr); + if (err == DB_OVERFLOW || err == DB_UNDERFLOW) { + err = DB_FAIL; + } + } else { + ut_a(mode == BTR_MODIFY_TREE); + err = btr_cur_pessimistic_update(BTR_KEEP_SYS_FLAG + | BTR_NO_LOCKING_FLAG, + btr_cur, &dummy_big_rec, + update, 0, thr, &mtr); + } + + mem_heap_free(heap); } btr_pcur_close(&pcur); mtr_commit(&mtr); + + return(err); } /*************************************************************** @@ -501,13 +548,14 @@ static ulint row_undo_mod_del_mark_sec( /*======================*/ - /* out: DB_SUCCESS */ + /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ undo_node_t* node, /* in: row undo node */ que_thr_t* thr) /* in: query thread */ { mem_heap_t* heap; dtuple_t* entry; dict_index_t* index; + ulint err; heap = mem_heap_create(1024); @@ -516,7 +564,21 @@ row_undo_mod_del_mark_sec( entry = row_build_index_entry(node->row, index, heap); - row_undo_mod_del_unmark_sec(node, thr, index, entry); + err = row_undo_mod_del_unmark_sec_and_undo_update( + BTR_MODIFY_LEAF, + node, thr, index, entry); + if (err == DB_FAIL) { + err = row_undo_mod_del_unmark_sec_and_undo_update( + BTR_MODIFY_TREE, + node, thr, index, entry); + } + + if (err != DB_SUCCESS) { + + mem_heap_free(heap); + + return(err); + } node->index = dict_table_get_next_index(node->index); } @@ -532,7 +594,7 @@ static ulint row_undo_mod_upd_exist_sec( /*=======================*/ - /* out: DB_SUCCESS or error code */ + /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ undo_node_t* node, /* in: row undo node */ que_thr_t* thr) /* in: query thread */ { @@ -558,22 +620,48 @@ row_undo_mod_upd_exist_sec( /* Build the newest version of the index entry */ entry = row_build_index_entry(node->row, index, heap); + /* NOTE that if we updated the fields of a + delete-marked secondary index record so that + alphabetically they stayed the same, e.g., + 'abc' -> 'aBc', we cannot return to the original + values because we do not know them. But this should + not cause problems because in row0sel.c, in queries + we always retrieve the clustered index record or an + earlier version of it, if the secondary index record + through which we do the search is delete-marked. */ + err = row_undo_mod_del_mark_or_remove_sec(node, thr, - index, entry); + index, entry); if (err != DB_SUCCESS) { mem_heap_free(heap); return(err); } - + /* We may have to update the delete mark in the secondary index record of the previous version of - the row */ + the row. We also need to update the fields of + the secondary index record if we updated its fields + but alphabetically they stayed the same, e.g., + 'abc' -> 'aBc'. */ row_upd_index_replace_new_col_vals(entry, index, node->update, NULL); + err = row_undo_mod_del_unmark_sec_and_undo_update( + BTR_MODIFY_LEAF, + node, thr, index, entry); + if (err == DB_FAIL) { + err = + row_undo_mod_del_unmark_sec_and_undo_update( + BTR_MODIFY_TREE, + node, thr, index, entry); + } - row_undo_mod_del_unmark_sec(node, thr, index, entry); + if (err != DB_SUCCESS) { + mem_heap_free(heap); + + return(err); + } } node->index = dict_table_get_next_index(node->index); From 00d339c4de1ac200f6684b1d7bf1d449f475afdb Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Fri, 12 Dec 2003 21:26:44 -0400 Subject: [PATCH 61/89] added checking for old cuted value in Field_enum::store (bug #2023) --- mysql-test/r/type_enum.result | 10 ++++++++++ mysql-test/t/type_enum.test | 11 +++++++++++ sql/field.cc | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index ee3bd077798..03cfdc3c286 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -1636,3 +1636,13 @@ t1 CREATE TABLE `t1` ( `a` enum('','a','b') NOT NULL default 'b' ) TYPE=MyISAM drop table t1; +create table t1 (a enum ('0','1')); +insert into t1 set a='foobar'; +select * from t1; +a + +update t1 set a = replace(a,'x','y'); +select * from t1; +a + +drop table t1; diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test index 8f399e4364e..78b850b6ea6 100644 --- a/mysql-test/t/type_enum.test +++ b/mysql-test/t/type_enum.test @@ -21,3 +21,14 @@ drop table t1; create table t1 (a enum (' ','a','b ') not null default 'b '); show create table t1; drop table t1; + +# +# Tests of wrong enum values (bug #2023) +# + +create table t1 (a enum ('0','1')); +insert into t1 set a='foobar'; +select * from t1; +update t1 set a = replace(a,'x','y'); +select * from t1; +drop table t1; \ No newline at end of file diff --git a/sql/field.cc b/sql/field.cc index d43089ec35c..a2734835cf9 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4623,7 +4623,7 @@ void Field_enum::store(const char *from,uint length) uint tmp=find_enum(typelib,from,length); if (!tmp) { - if (length < 6) // Can't be more than 99999 enums + if (from && length < 6) // Can't be more than 99999 enums { /* This is for reading numbers with LOAD DATA INFILE */ char buff[7], *end; From 5eb8fa9eafe73456905c1e8bb8ec2f5ea5fe6e57 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Fri, 12 Dec 2003 22:02:50 -0400 Subject: [PATCH 62/89] refixed last vva patch with monty's instructions --- sql/field.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index a2734835cf9..43244a2f8a6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4623,7 +4623,7 @@ void Field_enum::store(const char *from,uint length) uint tmp=find_enum(typelib,from,length); if (!tmp) { - if (from && length < 6) // Can't be more than 99999 enums + if (length < 6) // Can't be more than 99999 enums { /* This is for reading numbers with LOAD DATA INFILE */ char buff[7], *end; @@ -4721,7 +4721,7 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)), { uint tmp=(uint) Field_enum::val_int(); if (!tmp || tmp > typelib->count) - val_ptr->length(0); + val_ptr->set((char*)"",0); else val_ptr->set((const char*) typelib->type_names[tmp-1], (uint) strlen(typelib->type_names[tmp-1])); From 2f34b764b1526bd0a95b1502dcd3afca1fd456a1 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Sat, 13 Dec 2003 03:49:50 +0100 Subject: [PATCH 63/89] - Some small Perl enhancements for Do-compile: use more Perl builtins. --- Build-tools/Do-compile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index e5783dbf515..e92654ccffd 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -1,6 +1,8 @@ #!/usr/bin/perl -w +use File::Basename; use Getopt::Long; +use Sys::Hostname; @config_options= (); @make_options= (); @@ -75,7 +77,7 @@ if (@config_env > 0) $opt_config_env= join(" ", @config_env); } -chomp($host=`hostname`); +$host= hostname(); chomp($uname=`uname`); $full_host_name=$host; $connect_option= ($opt_tcpip ? "--host=$host" : ""); @@ -83,7 +85,7 @@ $host =~ /^([^.-]*)/; $host=$1 . $opt_suffix; $email="$opt_user\@mysql.com"; chomp($pwd = `pwd`); -$VER= `basename $opt_distribution`; chop $VER; +$VER= basename($opt_distribution); $VER=~ /mysql.*-([1-9]\.[0-9]{1,2}\.[0-9]{1,2}.*)\.tar*/; $version=$1; ($major, $minor, $release) = split(/\./,$version); $log="$pwd/Logs/$host-$major.$minor$opt_version_suffix.log"; @@ -110,7 +112,7 @@ if (defined($gcc_version) && ! $opt_config_env) $new_opt_tmp=0; if ($opt_tmp) { - if (! -d $opt_tmp) + unless (-d $opt_tmp) { safe_system("mkdir $opt_tmp"); $new_opt_tmp=1; From 1483e8d3720b7370d56d816ba5d09b526ac10b54 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Sat, 13 Dec 2003 03:52:19 +0100 Subject: [PATCH 64/89] - fixed file permissions for the server RPM docs directory (BUG 1672) --- support-files/mysql.spec.sh | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 1cb25e2ff42..e1c3476f738 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -442,11 +442,12 @@ fi [ "$RBR" != "/" ] && [ -d $RBR ] && rm -rf $RBR; %files server -%defattr(755 root, root) +%defattr(-,root,root,0755) -%doc %attr(644, root, root) COPYING README -%doc %attr(644, root, root) Docs/manual.{html,ps,texi,txt} Docs/manual_toc.html -%doc %attr(644, root, root) support-files/my-*.cnf +%doc COPYING README +%doc Docs/manual.{html,ps,texi,txt} +%doc Docs/manual_toc.html +%doc support-files/my-*.cnf %doc %attr(644, root, root) %{_infodir}/mysql.info* @@ -498,6 +499,7 @@ fi %attr(755, root, root) %{_datadir}/mysql/ %files client +%defattr(-, root, root, 0755) %attr(755, root, root) %{_bindir}/msql2mysql %attr(755, root, root) %{_bindir}/mysql %attr(755, root, root) %{_bindir}/mysql_find_rows @@ -525,7 +527,7 @@ fi /sbin/ldconfig %files devel -%defattr(644 root, root) +%defattr(-, root, root, 0755) %attr(755, root, root) %{_bindir}/comp_err %attr(755, root, root) %{_bindir}/mysql_config %dir %attr(755, root, root) %{_includedir}/mysql @@ -546,11 +548,12 @@ fi %{_libdir}/mysql/libvio.a %files shared -%defattr(755 root, root) +%defattr(-, root, root, 0755) # Shared libraries (omit for architectures that don't support them) %{_libdir}/*.so* %files bench +%defattr(-, root, root, 0755) %attr(-, root, root) %{_datadir}/sql-bench %attr(-, root, root) %{_datadir}/mysql-test %attr(755, root, root) %{_bindir}/mysqlmanager @@ -558,15 +561,21 @@ fi %attr(755, root, root) %{_bindir}/mysqlmanagerc %files Max +%defattr(-, root, root, 0755) %attr(755, root, root) %{_sbindir}/mysqld-max %attr(644, root, root) %{_libdir}/mysql/mysqld-max.sym %files embedded +%defattr(-, root, root, 0755) %attr(644, root, root) %{_libdir}/mysql/libmysqld.a # The spec file changelog only includes changes made to the spec file # itself %changelog +* Fri Dec 13 2003 Lenz Grimmer + +- fixed file permissions (BUG 1672) + * Thu Dec 11 2003 Lenz Grimmer - made testing for gcc3 a bit more robust From 8411769272b6699e76fa11a23b930e3be6b16ebf Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Sat, 13 Dec 2003 04:23:07 +0100 Subject: [PATCH 65/89] - added missing space for previous commit --- Build-tools/Bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index c1a416356f1..a08006e1eac 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -279,7 +279,7 @@ unless ($opt_skip_manual) foreach $file qw/internals manual reservedwords/ { $command= "bk cat $opt_docdir/Docs/$file.texi"; - $command.= "> $target_dir/Docs/$file.texi"; + $command.= " > $target_dir/Docs/$file.texi"; &run_command($command, "Could not updated $file.texi in $target_dir/Docs/!"); } } From 9f9510026fe9ec45451217902dd49379fa05a934 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Sat, 13 Dec 2003 04:33:36 +0100 Subject: [PATCH 66/89] - Output redirection does not work with run_command(), use system() instead. --- Build-tools/Bootstrap | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index a08006e1eac..7d3ac1322f4 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -278,9 +278,8 @@ unless ($opt_skip_manual) &logger($msg); foreach $file qw/internals manual reservedwords/ { - $command= "bk cat $opt_docdir/Docs/$file.texi"; - $command.= " > $target_dir/Docs/$file.texi"; - &run_command($command, "Could not updated $file.texi in $target_dir/Docs/!"); + system ("bk cat $opt_docdir/Docs/$file.texi > $target_dir/Docs/$file.texi") == 0 + or &abort("Could not update $file.texi in $target_dir/Docs/!"); } } From b5f0d76b8a080e85f757753045272c3326aedbe5 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Sat, 13 Dec 2003 14:51:05 +0200 Subject: [PATCH 67/89] Changing a maxumum value for a variable at a request of one customer and Dean Ellis. --- client/mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index 083e8fd6ac3..3f3b01c1034 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -574,7 +574,7 @@ static struct my_option my_long_options[] = 0, 1}, {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_ULONG, - REQUIRED_ARG, 16 *1024L*1024L, 4096, 512*1024L*1024L, MALLOC_OVERHEAD, + REQUIRED_ARG, 16 *1024L*1024L, 4096, 2*1024*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_ULONG, From d47deebb58804e2323d3861d0cf4d68f5cfea04f Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Sun, 14 Dec 2003 06:39:52 +0200 Subject: [PATCH 68/89] Extend max_allowed_packet to 2G in mysql and mysqldump (Bug #2105) Don't dump data for MRG_ISAM or MRG_MYISAM tables. (Bug #1846) Ensure that 'lower_case_table_names' is always set on case insensitive file systems. (Bug #1812) One can now configure MySQL as windows service as a normal user. (Bug #1802) Database names is now compared with lower case in ON clause when lower_case_table_names is set. (Bug #1736) IGNORE ... LINES option didn't work when used with fixed length rows. (Bug #1704) Change INSERT DELAYED ... SELECT... to INSERT .... SELECT (Bug #1983) Safety fix for service 'mysql start' (Bug #1815) --- client/mysql.cc | 4 +- client/mysqldump.c | 103 ++++++++++++++++++++++++++-- configure.in | 2 +- include/my_global.h | 3 + mysql-test/r/insert.result | 2 +- mysql-test/r/loaddata.result | 18 +++++ mysql-test/r/lowercase_table.result | 10 ++- mysql-test/std_data/loaddata3.dat | 6 ++ mysql-test/std_data/loaddata4.dat | 1 + mysql-test/t/insert.test | 2 +- mysql-test/t/loaddata.test | 11 +++ mysql-test/t/lowercase_table.test | 7 +- sql/item.cc | 8 +++ sql/item.h | 4 +- sql/mysqld.cc | 92 +++++++++++++++++++------ sql/nt_servc.cc | 4 +- sql/sql_base.cc | 13 ++++ sql/sql_class.h | 2 +- sql/sql_load.cc | 63 +++++++++++++---- sql/sql_parse.cc | 13 ++-- strings/ctype-tis620.c | 18 +++-- support-files/mysql.server.sh | 2 +- 22 files changed, 318 insertions(+), 70 deletions(-) create mode 100644 mysql-test/std_data/loaddata3.dat create mode 100644 mysql-test/std_data/loaddata4.dat diff --git a/client/mysql.cc b/client/mysql.cc index 083e8fd6ac3..370213d4fc4 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -574,8 +574,8 @@ static struct my_option my_long_options[] = 0, 1}, {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, GET_ULONG, - REQUIRED_ARG, 16 *1024L*1024L, 4096, 512*1024L*1024L, MALLOC_OVERHEAD, - 1024, 0}, + REQUIRED_ARG, 16 *1024L*1024L, 4096, (longlong) 2*1024L*1024L*1024L, + MALLOC_OVERHEAD, 1024, 0}, {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 16384, 1024, 512*1024*1024L, MALLOC_OVERHEAD, 1024, 0}, diff --git a/client/mysqldump.c b/client/mysqldump.c index d8e63cd611a..489869f6c3d 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -36,7 +36,7 @@ ** Added --single-transaction option 06/06/2002 by Peter Zaitsev */ -#define DUMP_VERSION "9.09" +#define DUMP_VERSION "9.10" #include #include @@ -236,8 +236,8 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET, "", (gptr*) &max_allowed_packet, (gptr*) &max_allowed_packet, 0, - GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096, 1024*1024L*1024L, - MALLOC_OVERHEAD, 1024, 0}, + GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096, + (longlong) 2L*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, {"net_buffer_length", OPT_NET_BUFFER_LENGTH, "", (gptr*) &net_buffer_length, (gptr*) &net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L, @@ -262,6 +262,8 @@ static int dump_databases(char **); static int dump_all_databases(); static char *quote_name(const char *name, char *buff, my_bool force); static void print_quoted_xml(FILE *output, char *fname, char *str, uint len); +static const char *check_if_ignore_table(const char *table_name); + static void print_version(void) { @@ -564,6 +566,23 @@ static char *quote_name(const char *name, char *buff, my_bool force) } /* quote_name */ + +static char *quote_for_like(const char *name, char *buff) +{ + char *to= buff; + *to++= '\''; + while (*name) + { + if (*name == '\'' || *name == '_' || *name == '\\' || *name == '%') + *to++= '\\'; + *to++= *name++; + } + to[0]= '\''; + to[1]= 0; + return buff; +} + + /* getStructure -- retrievs database structure, prints out corresponding CREATE statement and fills out insert_pat. @@ -590,7 +609,8 @@ static uint getTableStructure(char *table, char* db) if (verbose) fprintf(stderr, "-- Retrieving table structure for table %s...\n", table); - sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", (opt_quoted || opt_keywords)); + sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", + (opt_quoted || opt_keywords)); result_table= quote_name(table, table_buff, 1); opt_quoted_table= quote_name(table, table_buff2, 0); if (!mysql_query(sock,insert_pat)) @@ -819,7 +839,9 @@ static uint getTableStructure(char *table, char* db) /* Get MySQL specific create options */ if (create_options) { - sprintf(buff,"show table status like %s",result_table); + char show_name_buff[FN_REFLEN]; + sprintf(buff,"show table status like %s", + quote_for_like(table, show_name_buff)); if (mysql_query(sock, buff)) { if (mysql_errno(sock) != ER_PARSE_ERROR) @@ -924,11 +946,23 @@ static void dumpTable(uint numFields, char *table) MYSQL_FIELD *field; MYSQL_ROW row; ulong rownr, row_break, total_length, init_length; + const char *table_type; + + result_table= quote_name(table,table_buff, 1); + opt_quoted_table= quote_name(table, table_buff2, 0); + + /* Check table type */ + if ((table_type= check_if_ignore_table(table))) + { + if (verbose) + fprintf(stderr, + "-- Skipping data for table '%s' because it's of type %s\n", + table, table_type); + return; + } if (verbose) fprintf(stderr, "-- Sending SELECT query...\n"); - result_table= quote_name(table,table_buff, 1); - opt_quoted_table= quote_name(table, table_buff2, 0); if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; @@ -1434,6 +1468,61 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, } /* print_value */ +/* + Check if we the table is one of the table types that should be ignored: + MRG_ISAM, MRG_MYISAM + + SYNOPSIS + check_if_ignore_table() + table_name Table name to check + + GLOBAL VARIABLES + sock MySQL socket + verbose Write warning messages + + RETURN + 0 Table should be backuped + # Type of table (that should be skipped) +*/ + +static const char *check_if_ignore_table(const char *table_name) +{ + char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN]; + MYSQL_RES *res; + MYSQL_ROW row; + const char *result= 0; + + sprintf(buff,"show table status like %s", + quote_for_like(table_name, show_name_buff)); + if (mysql_query(sock, buff)) + { + if (mysql_errno(sock) != ER_PARSE_ERROR) + { /* If old MySQL version */ + if (verbose) + fprintf(stderr, + "-- Warning: Couldn't get status information for table %s (%s)\n", + table_name,mysql_error(sock)); + return 0; /* assume table is ok */ + } + } + if (!(res= mysql_store_result(sock)) || + !(row= mysql_fetch_row(res))) + { + fprintf(stderr, + "Error: Couldn't read status information for table %s (%s)\n", + table_name, mysql_error(sock)); + if (res) + mysql_free_result(res); + return 0; /* assume table is ok */ + } + if (strcmp(row[1], (result= "MRG_MyISAM")) && + strcmp(row[1], (result= "MRG_ISAM"))) + result= 0; + mysql_free_result(res); + return result; +} + + int main(int argc, char **argv) { MYSQL_ROW row; diff --git a/configure.in b/configure.in index a4fe75ce896..7260a21428d 100644 --- a/configure.in +++ b/configure.in @@ -733,7 +733,7 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \ strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \ sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \ unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \ - sys/ioctl.h malloc.h sys/malloc.h) + sys/ioctl.h malloc.h sys/malloc.h linux/config.h) #-------------------------------------------------------------------- # Check for system libraries. Adds the library to $LIBS diff --git a/include/my_global.h b/include/my_global.h index bcd6004d72a..168961a620d 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -267,6 +267,9 @@ C_MODE_END #endif #ifdef HAVE_ATOMIC_ADD #define __SMP__ +#ifdef HAVE_LINUX_CONFIG_H +#include /* May define CONFIG_SMP */ +#endif #ifndef CONFIG_SMP #define CONFIG_SMP #endif diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 270994e3998..7520fd7e6cc 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -71,7 +71,7 @@ drop table t1; create table t1 (email varchar(50)); insert into t1 values ('sasha@mysql.com'),('monty@mysql.com'),('foo@hotmail.com'),('foo@aol.com'),('bar@aol.com'); create table t2(id int not null auto_increment primary key, t2 varchar(50), unique(t2)); -insert into t2 (t2) select distinct substring(email, locate('@', email)+1) from t1; +insert delayed into t2 (t2) select distinct substring(email, locate('@', email)+1) from t1; select * from t2; id t2 1 mysql.com diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index 0b7925de1c5..1730d7b5c25 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -26,3 +26,21 @@ Field 3,'Field 4| |Field 5' ,'Field 6| NULL |Field 6| | 'Field 7'| drop table t1; +create table t1 (a int, b char(10)); +load data infile '../../std_data/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines; +select * from t1; +a b +1 row 1 +2 row 2 +0 1234567890 +3 row 3 +0 1234567890 +truncate table t1; +load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines; +select * from t1; +a b +1 row 1 +2 row 2 +3 row 3 +0 +drop table t1; diff --git a/mysql-test/r/lowercase_table.result b/mysql-test/r/lowercase_table.result index 8edf43a51ad..16bc92cb711 100644 --- a/mysql-test/r/lowercase_table.result +++ b/mysql-test/r/lowercase_table.result @@ -1,6 +1,8 @@ -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,T1; create table T1 (id int primary key, Word varchar(40) not null, Index(Word)); +create table t4 (id int primary key, Word varchar(40) not null); INSERT INTO T1 VALUES (1, 'a'), (2, 'b'), (3, 'c'); +INSERT INTO T4 VALUES(1,'match'); SELECT * FROM t1; id Word 1 a @@ -12,6 +14,9 @@ id SELECT T2.id from t1 as T2 LIMIT 1; id 1 +SELECT * from t1 left join t4 on (test.t1.id= TEST.t4.id) where TEST.t1.id >= test.t4.id; +id Word id Word +1 a 1 match SELECT T2.id from t1 as t2 LIMIT 1; Unknown table 'T2' in field list RENAME TABLE T1 TO T2; @@ -20,7 +25,8 @@ ALTER TABLE T2 RENAME T3; show tables like 't_'; Tables_in_test (t_) t3 -drop table t3; +t4 +drop table t3,t4; create table t1 (a int); select count(*) from T1; count(*) diff --git a/mysql-test/std_data/loaddata3.dat b/mysql-test/std_data/loaddata3.dat new file mode 100644 index 00000000000..4c82f1396c5 --- /dev/null +++ b/mysql-test/std_data/loaddata3.dat @@ -0,0 +1,6 @@ +number row data +1 row 1 +2 row 2 +error 12345678901234567890123456789012345678901234567890 +3 row 3 +wrong end 12345678901234567890123456789012345678901234567890 diff --git a/mysql-test/std_data/loaddata4.dat b/mysql-test/std_data/loaddata4.dat new file mode 100644 index 00000000000..9c0d744438c --- /dev/null +++ b/mysql-test/std_data/loaddata4.dat @@ -0,0 +1 @@ +test row data 1 row 1 2 row 2 3 row 3 diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index fbb9134ff7f..12dfe6e50a9 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -68,7 +68,7 @@ drop table t1; create table t1 (email varchar(50)); insert into t1 values ('sasha@mysql.com'),('monty@mysql.com'),('foo@hotmail.com'),('foo@aol.com'),('bar@aol.com'); create table t2(id int not null auto_increment primary key, t2 varchar(50), unique(t2)); -insert into t2 (t2) select distinct substring(email, locate('@', email)+1) from t1; +insert delayed into t2 (t2) select distinct substring(email, locate('@', email)+1) from t1; select * from t2; drop table t1,t2; diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test index 732ed248702..9269eb19b05 100644 --- a/mysql-test/t/loaddata.test +++ b/mysql-test/t/loaddata.test @@ -18,3 +18,14 @@ create table t1 (a text, b text); load data infile '../../std_data/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; select concat('|',a,'|'), concat('|',b,'|') from t1; drop table t1; + +create table t1 (a int, b char(10)); +load data infile '../../std_data/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines; +select * from t1; +truncate table t1; +load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines; + +# The empty line last comes from the end line field in the file +select * from t1; +drop table t1; + diff --git a/mysql-test/t/lowercase_table.test b/mysql-test/t/lowercase_table.test index 86ea2918fd2..5bc19f26c0e 100644 --- a/mysql-test/t/lowercase_table.test +++ b/mysql-test/t/lowercase_table.test @@ -2,19 +2,22 @@ # Test of --lower-case-table-names # -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,T1; create table T1 (id int primary key, Word varchar(40) not null, Index(Word)); +create table t4 (id int primary key, Word varchar(40) not null); INSERT INTO T1 VALUES (1, 'a'), (2, 'b'), (3, 'c'); +INSERT INTO T4 VALUES(1,'match'); SELECT * FROM t1; SELECT T1.id from T1 LIMIT 1; SELECT T2.id from t1 as T2 LIMIT 1; +SELECT * from t1 left join t4 on (test.t1.id= TEST.t4.id) where TEST.t1.id >= test.t4.id; --error 1109 SELECT T2.id from t1 as t2 LIMIT 1; RENAME TABLE T1 TO T2; ALTER TABLE T2 ADD new_col int not null; ALTER TABLE T2 RENAME T3; show tables like 't_'; -drop table t3; +drop table t3,t4; # # Test alias diff --git a/sql/item.cc b/sql/item.cc index 60fc383d757..fcc9372773a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -117,6 +117,14 @@ bool Item::get_time(TIME *ltime) return 0; } +Item_ident::Item_ident(const char *db_name_par,const char *table_name_par, + const char *field_name_par) + :db_name(db_name_par),table_name(table_name_par),field_name(field_name_par) +{ + name = (char*) field_name_par; +} + + Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) { set_field(f); diff --git a/sql/item.h b/sql/item.h index e8a6313b6a0..f96f4cd506a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -119,9 +119,7 @@ public: const char *table_name; const char *field_name; Item_ident(const char *db_name_par,const char *table_name_par, - const char *field_name_par) - :db_name(db_name_par),table_name(table_name_par),field_name(field_name_par) - { name = (char*) field_name_par; } + const char *field_name_par); const char *full_name() const; unsigned int size_of() { return sizeof(*this);} }; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b75a94a261c..1bdb2300aba 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -500,6 +500,8 @@ static uint set_maximum_open_files(uint max_file_limit); static ulong find_bit_type(const char *x, TYPELIB *bit_lib); static void clean_up(bool print_message); static void clean_up_mutexes(void); +static int test_if_case_insensitive(const char *dir_name); +static void create_pid_file(); /**************************************************************************** ** Code to end mysqld @@ -1459,17 +1461,7 @@ static void start_signal_handler(void) { // Save vm id of this process if (!opt_bootstrap) - { - File pidFile; - if ((pidFile = my_create(pidfile_name,0664, - O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0) - { - char buff[21]; - sprintf(buff,"%lu\n",(ulong) getpid()); - (void) my_write(pidFile, buff,strlen(buff),MYF(MY_WME)); - (void) my_close(pidFile,MYF(0)); - } - } + create_pid_file(); // no signal handler } @@ -1753,17 +1745,8 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) /* Save pid to this process (or thread on Linux) */ if (!opt_bootstrap) - { - File pidFile; - if ((pidFile = my_create(pidfile_name,0664, - O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0) - { - char buff[21]; - sprintf(buff,"%lu",(ulong) getpid()); - (void) my_write(pidFile, buff,strlen(buff),MYF(MY_WME)); - (void) my_close(pidFile,MYF(0)); - } - } + create_pid_file(); + #ifdef HAVE_STACK_TRACE_ON_SEGV if (opt_do_pstack) { @@ -4963,6 +4946,17 @@ static void fix_paths(void) if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE)))) exit(1); } + + /* + Ensure that lower_case_table_names is set on system where we have case + insensitive names. If this is not done the users MyISAM tables will + get corrupted if accesses with names of different case. + */ + if (!lower_case_table_names && + test_if_case_insensitive(mysql_real_data_home) == 1) + { + sql_print_error("Warning: Setting lower_case_table_names=1 becasue file system %s is case insensitve", mysql_real_data_home); + } } @@ -5096,6 +5090,60 @@ skipp: ; } /* find_bit_type */ +/* + Check if file system used for databases is case insensitive + + SYNOPSIS + test_if_case_sensitive() + dir_name Directory to test + + RETURN + -1 Don't know (Test failed) + 0 File system is case sensitive + 1 File system is case insensitive +*/ + +static int test_if_case_insensitive(const char *dir_name) +{ + int result= 0; + File file; + char buff[FN_REFLEN], buff2[FN_REFLEN]; + MY_STAT stat_info; + + fn_format(buff, glob_hostname, dir_name, ".lower-test", + MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR); + fn_format(buff2, glob_hostname, dir_name, ".LOWER-TEST", + MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR); + (void) my_delete(buff2, MYF(0)); + if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0) + { + sql_print_error("Warning: Can't create test file %s", buff); + return -1; + } + my_close(file, MYF(0)); + if (my_stat(buff2, &stat_info, MYF(0))) + result= 1; // Can access file + (void) my_delete(buff, MYF(MY_WME)); + return result; +} + + +/* Create file to store pid number */ + +static void create_pid_file() +{ + File file; + if ((file = my_create(pidfile_name,0664, + O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0) + { + char buff[21]; + sprintf(buff,"%lu\n",(ulong) getpid()); + (void) my_write(file, buff,strlen(buff),MYF(MY_WME)); + (void) my_close(file, MYF(0)); + } +} + + /***************************************************************************** Instantiate templates *****************************************************************************/ diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index b18d3d00d88..8a3757a9768 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -496,9 +496,9 @@ BOOL NTService::IsService(LPCSTR ServiceName) BOOL ret_value=FALSE; SC_HANDLE service, scm; - if (scm = OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE)) + if ((scm= OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE))) { - if ((service = OpenService(scm,ServiceName, SERVICE_ALL_ACCESS ))) + if ((service = OpenService(scm,ServiceName, SERVICE_QUERY_STATUS ))) { ret_value=TRUE; CloseServiceHandle(service); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index dd80062d6e7..e65b84ff184 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1721,6 +1721,19 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) const char *table_name=item->table_name; const char *name=item->field_name; uint length=(uint) strlen(name); + char name_buff[NAME_LEN+1]; + + if (db && lower_case_table_names) + { + /* + convert database to lower case for comparision. + We can't do this in Item_field as this would change the + 'name' of the item which may be used in the select list + */ + strmake(name_buff, db, sizeof(name_buff)-1); + casedn_str(name_buff); + db= name_buff; + } if (table_name) { /* Qualified field */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 0d0e0d7fbc5..e4e118c0b29 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -608,7 +608,7 @@ public: String *field_term,*enclosed,*line_term,*line_start,*escaped; bool opt_enclosed; bool dumpfile; - uint skip_lines; + ulong skip_lines; sql_exchange(char *name,bool dumpfile_flag); ~sql_exchange() {} }; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index e692e7b8dab..7c3e7b8e877 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -71,10 +71,11 @@ public: }; static int read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table, - List &fields, READ_INFO &read_info); + List &fields, READ_INFO &read_info, + ulong skip_lines); static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, List &fields, READ_INFO &read_info, - String &enclosed); + String &enclosed, ulong skip_lines); int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, @@ -85,14 +86,15 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, File file; TABLE *table; int error; - String *field_term=ex->field_term,*escaped=ex->escaped, - *enclosed=ex->enclosed; + String *field_term=ex->field_term,*escaped=ex->escaped; + String *enclosed=ex->enclosed; bool is_fifo=0; LOAD_FILE_INFO lf_info; char *db = table_list->db; // This is never null /* If no current database, use database where table is located */ char *tdb= thd->db ? thd->db : db; bool transactional_table, log_delayed; + ulong skip_lines= ex->skip_lines; DBUG_ENTER("mysql_load"); #ifdef EMBEDDED_LIBRARY @@ -235,16 +237,18 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, thd->count_cuted_fields=1; /* calc cuted fields */ thd->cuted_fields=0L; - if (ex->line_term->length() && field_term->length()) + /* Skip lines if there is a line terminator */ + if (ex->line_term->length()) { - // ex->skip_lines needs to be preserved for logging - uint skip_lines = ex->skip_lines; - while (skip_lines--) + /* ex->skip_lines needs to be preserved for logging */ + while (skip_lines > 0) { + skip_lines--; if (read_info.next_line()) break; } } + if (!(error=test(read_info.error))) { uint save_time_stamp=table->time_stamp; @@ -260,9 +264,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, table->file->deactivate_non_unique_index((ha_rows) 0); table->copy_blobs=1; if (!field_term->length() && !enclosed->length()) - error=read_fixed_length(thd,info,table,fields,read_info); + error=read_fixed_length(thd,info,table,fields,read_info, + skip_lines); else - error=read_sep_field(thd,info,table,fields,read_info,*enclosed); + error=read_sep_field(thd,info,table,fields,read_info,*enclosed, + skip_lines); if (table->file->extra(HA_EXTRA_NO_CACHE)) error=1; /* purecov: inspected */ if (table->file->activate_all_index(thd)) @@ -271,7 +277,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, table->time_stamp=save_time_stamp; table->next_number_field=0; } - if (file >= 0) my_close(file,MYF(0)); + if (file >= 0) + my_close(file,MYF(0)); free_blobs(table); /* if pack_blob was used */ table->copy_blobs=0; thd->count_cuted_fields=0; /* Don`t calc cuted fields */ @@ -369,7 +376,7 @@ err: static int read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List &fields, - READ_INFO &read_info) + READ_INFO &read_info, ulong skip_lines) { List_iterator_fast it(fields); Item_field *sql_field; @@ -388,6 +395,17 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List &fields, my_error(ER_SERVER_SHUTDOWN,MYF(0)); DBUG_RETURN(1); } + if (skip_lines) + { + /* + We could implement this with a simple seek if: + - We are not using DATA INFILE LOCAL + - escape character is "" + - line starting prefix is "" + */ + skip_lines--; + continue; + } it.rewind(); byte *pos=read_info.row_start; #ifdef HAVE_purify @@ -444,7 +462,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List &fields, static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, List &fields, READ_INFO &read_info, - String &enclosed) + String &enclosed, ulong skip_lines) { List_iterator_fast it(fields); Item_field *sql_field; @@ -494,6 +512,12 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, } if (read_info.error) break; + if (skip_lines) + { + if (!--skip_lines) + thd->cuted_fields= 0L; // Reset warnings + continue; + } if (sql_field) { // Last record if (sql_field == (Item_field*) fields.head()) @@ -821,7 +845,18 @@ found_eof: } /* -** One can't use fixed length with multi-byte charset ** + Read a row with fixed length. + + NOTES + The row may not be fixed size on disk if there are escape + characters in the file. + + IMPLEMENTATION NOTE + One can't use fixed length with multi-byte charset ** + + RETURN + 0 ok + 1 error */ int READ_INFO::read_fixed_length() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 01d6500260f..d59a26f5ce8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1971,12 +1971,11 @@ mysql_execute_command(void) case SQLCOM_REPLACE_SELECT: case SQLCOM_INSERT_SELECT: { - - /* - Check that we have modify privileges for the first table and - select privileges for the rest - */ { + /* + Check that we have modify privileges for the first table and + select privileges for the rest + */ ulong privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ? INSERT_ACL : INSERT_ACL | DELETE_ACL); TABLE_LIST *save_next=tables->next; @@ -1989,6 +1988,10 @@ mysql_execute_command(void) if ((res=check_table_access(thd, SELECT_ACL, save_next))) goto error; } + /* Fix lock for first table */ + if (tables->lock_type == TL_WRITE_DELAYED) + tables->lock_type == TL_WRITE; + /* Don't unlock tables until command is written to binary log */ select_lex->options|= SELECT_NO_UNLOCK; diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index edadadf3a43..7ffc83ea005 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -538,8 +538,10 @@ int my_strnncoll_tis620(const uchar * s1, int len1, const uchar * s2, int len2) tc1= thai2sortable(s1, len1); tc2= thai2sortable(s2, len2); i= strcmp((char*)tc1, (char*)tc2); - free(tc1); - free(tc2); + if (tc1 != s1) + free(tc1); + if (tc2 != s2) + free(tc2); return i; } @@ -555,7 +557,8 @@ int my_strnxfrm_tis620(uchar * dest, const uchar * src, int len, int srclen) tmp= thai2sortable(src,srclen); set_if_smaller(bufSize,(uint) len); memcpy((uchar *)dest, tmp, bufSize); - free(tmp); + if (tmp != src) + free(tmp); return (int)bufSize; } @@ -570,8 +573,10 @@ int my_strcoll_tis620(const uchar * s1, const uchar * s2) tc1= thai2sortable(s1, (int) strlen((char*)s1)); tc2= thai2sortable(s2, (int) strlen((char*)s2)); i= strcmp((char*)tc1, (char*)tc2); - free(tc1); - free(tc2); + if (tc1 != s1) + free(tc1); + if (tc2 != s2) + free(tc2); return i; } @@ -587,7 +592,8 @@ int my_strxfrm_tis620(uchar * dest, const uchar * src, int len) bufSize= (uint)buffsize((char*) src); tmp= thai2sortable(src, len); memcpy((uchar *)dest, tmp, bufSize); - free(tmp); + if (tmp != src) + free(tmp); return bufSize; } diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index 36eb5c4dff6..d55068db64e 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -145,7 +145,7 @@ case "$mode" in then # Give extra arguments to mysqld with the my.cnf file. This script may # be overwritten at next upgrade. - $bindir/mysqld_safe --datadir=$datadir --pid-file=$pid_file & + $bindir/mysqld_safe --datadir=$datadir --pid-file=$pid_file >/dev/null 2>&1 & # Make lock for RedHat / SuSE if test -w /var/lock/subsys then From 427ce41c3c29edc5fa357bf342b369e0a0611b98 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Sun, 14 Dec 2003 08:12:07 -0500 Subject: [PATCH 69/89] Fixed bug in last push found by valgrind --- myisam/mi_dbug.c | 4 ++++ sql/opt_range.cc | 15 +++++++-------- sql/sql_update.cc | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/myisam/mi_dbug.c b/myisam/mi_dbug.c index 482287938c0..fe5b36fd304 100644 --- a/myisam/mi_dbug.c +++ b/myisam/mi_dbug.c @@ -137,6 +137,10 @@ void _mi_print_key(FILE *stream, register MI_KEYSEG *keyseg, { uint tmp_length; get_key_length(tmp_length,key); + /* + The following command sometimes gives a warning from valgrind. + Not yet sure if the bug is in valgrind, glibc or mysqld + */ VOID(fprintf(stream,"%.*s",(int) tmp_length,key)); key+=tmp_length; break; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 74fa237fd73..74e3f855db7 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1062,7 +1062,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, if (field->key_type() == HA_KEYTYPE_VARTEXT) copies= 2; str= str2= (char*) alloc_root(param->mem_root, - (key_part->part_length+maybe_null)*copies); + (key_part->part_length+maybe_null)*copies+1); if (!str) DBUG_RETURN(0); if (maybe_null) @@ -1078,16 +1078,15 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, uint length= uint2korr(str+maybe_null); char *end; str2= str+ key_part->part_length + maybe_null; - /* remove end space. The 2 is for the packed length */ - while (length > 0 && str[length+2+maybe_null-1] == ' ') + /* remove end space */ + while (length > 0 && str[length+HA_KEY_BLOB_LENGTH+maybe_null-1] == ' ') length--; int2store(str+maybe_null, length); /* Create key that is space filled */ - memcpy(str2, str, length+2+maybe_null); - end= str2+ maybe_null + key_part->part_length; - for (char *pos= str2+ 2+ length + maybe_null; pos < end ; pos++) - *pos++= ' '; - int2store(str2+maybe_null, key_part->part_length); + memcpy(str2, str, length + HA_KEY_BLOB_LENGTH + maybe_null); + bfill(str2+ length+ HA_KEY_BLOB_LENGTH +maybe_null, + key_part->part_length-length - HA_KEY_BLOB_LENGTH, ' '); + int2store(str2+maybe_null, key_part->part_length - HA_KEY_BLOB_LENGTH); } if (!(tree=new SEL_ARG(field,str,str2))) DBUG_RETURN(0); // out of memory diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 36ceef23740..27b498d350f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -440,7 +440,7 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, :all_tables(table_list), update_tables(0), thd(thd_arg), tmp_tables(0), updated(0), found(0), fields(field_list), values(value_list), table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg), - do_update(1), trans_safe(0) + do_update(1), trans_safe(0), transactional_tables(1) {} From 217226f9afcefb7918ce0aee5ac920dfdf73edf0 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Sun, 14 Dec 2003 21:31:02 +0100 Subject: [PATCH 70/89] Portablity fix --- mysql-test/r/have_met_timezone.require | 4 ++-- mysql-test/r/mysqldump.result | 2 +- mysql-test/r/timezone.result | 15 +++++++++------ mysql-test/t/mysqldump.test | 3 +++ mysql-test/t/timezone.test | 18 ++++++++++++------ 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/have_met_timezone.require b/mysql-test/r/have_met_timezone.require index 4ab263e2c0d..b3fde075ebd 100644 --- a/mysql-test/r/have_met_timezone.require +++ b/mysql-test/r/have_met_timezone.require @@ -1,2 +1,2 @@ -Variable_name Value -timezone MET +FROM_UNIXTIME(24*3600) +1970-01-02 01:00:00 diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 27ca3fbaaf5..837a3627647 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -32,6 +32,6 @@ CREATE TABLE t1 ( a double default NULL ) TYPE=MyISAM; -INSERT INTO t1 VALUES (NULL); +INSERT INTO t1 VALUES (RES); DROP TABLE t1; diff --git a/mysql-test/r/timezone.result b/mysql-test/r/timezone.result index de75e649ee4..20706408075 100644 --- a/mysql-test/r/timezone.result +++ b/mysql-test/r/timezone.result @@ -1,4 +1,13 @@ DROP TABLE IF EXISTS t1; +show variables like "timezone"; +Variable_name Value +timezone MET +select @a:=FROM_UNIXTIME(1); +@a:=FROM_UNIXTIME(1) +1970-01-01 01:00:01 +select unix_timestamp(@a); +unix_timestamp(@a) +1 CREATE TABLE t1 (ts int); INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00')); INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00')); @@ -23,9 +32,3 @@ ts from_unixtime(ts) 1048989599 2003-03-30 03:59:59 1048989601 2003-03-30 04:00:01 DROP TABLE t1; -select @a:=FROM_UNIXTIME(1); -@a:=FROM_UNIXTIME(1) -1970-01-01 01:00:01 -select unix_timestamp(@a); -unix_timestamp(@a) -1 diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 525949bd602..bc63dc37d96 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -25,5 +25,8 @@ DROP TABLE t1; CREATE TABLE t1 (a double); INSERT INTO t1 VALUES (-9e999999); +# The following replaces is here because some systems replaces the above +# double with '-inf' and others with MAX_DOUBLE +--replace_result (-1.79769313486232e+308) (RES) (NULL) (RES) --exec $MYSQL_DUMP --skip-comments test t1 DROP TABLE t1; diff --git a/mysql-test/t/timezone.test b/mysql-test/t/timezone.test index d9603c51766..ab732c11a34 100644 --- a/mysql-test/t/timezone.test +++ b/mysql-test/t/timezone.test @@ -3,7 +3,7 @@ -- require r/have_met_timezone.require disable_query_log; -show variables like "timezone"; +select FROM_UNIXTIME(24*3600); enable_query_log; # Initialization @@ -11,6 +11,17 @@ enable_query_log; DROP TABLE IF EXISTS t1; --enable_warnings +show variables like "timezone"; + +# +# Test unix timestamp +# +select @a:=FROM_UNIXTIME(1); +select unix_timestamp(@a); + +# +# Test of some values, including some with daylight saving time +# CREATE TABLE t1 (ts int); INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00')); @@ -27,8 +38,3 @@ INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 04:00:01')); SELECT ts,from_unixtime(ts) FROM t1; DROP TABLE t1; -# -# Test unix timestamp -# -select @a:=FROM_UNIXTIME(1); -select unix_timestamp(@a); From db2d812d1b2b554e10cebf9809e26d1d1dc4bbc9 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Tue, 16 Dec 2003 11:10:50 +0100 Subject: [PATCH 71/89] Fix for BUG#2083 "EE_ error codes (EE_DELETE, EE_WRITE) end up in the binlog, making slave stop". The problem was that during execution of the command on the master, an error can occur (for example, not space left on device, then mysqld waits and when there is space it completes successfully: so finally it worked but the error EE_WRITE remains in thd->net.last_errno and thd->net.last_error). To know if finally the command succeeded, we test the 'error' variable in every place, and if it shows no failure we reset thd->net.last_err* using the function THD::clear_error() which is backported from 4.1. A new test to see if now only real errors get to the binlog (note: the test uses "rm"). Also a bit of memory free/alloc saving in log_event.cc (do not free the whole mem_root after every query in the slave SQL thread: we can keep the initial block of it; which will be freed when the thread terminates). --- mysql-test/r/rpl_EE_error.result | 16 ++++++++++++++++ mysql-test/t/rpl_EE_error.test | 30 ++++++++++++++++++++++++++++++ sql/log_event.cc | 6 +++--- sql/sql_acl.cc | 1 + sql/sql_base.cc | 2 +- sql/sql_class.h | 9 +++++++++ sql/sql_db.cc | 2 ++ sql/sql_delete.cc | 5 +++++ sql/sql_insert.cc | 6 +++++- sql/sql_parse.cc | 2 ++ sql/sql_rename.cc | 1 + sql/sql_table.cc | 5 +++++ sql/sql_update.cc | 4 ++++ 13 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 mysql-test/r/rpl_EE_error.result create mode 100644 mysql-test/t/rpl_EE_error.test diff --git a/mysql-test/r/rpl_EE_error.result b/mysql-test/r/rpl_EE_error.result new file mode 100644 index 00000000000..a5043250df6 --- /dev/null +++ b/mysql-test/r/rpl_EE_error.result @@ -0,0 +1,16 @@ +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; +create table t1 (a int) type=myisam; +flush tables; +drop table t1; +create table t1 (a int, unique(a)) type=myisam; +set sql_log_bin=0; +insert into t1 values(2); +set sql_log_bin=1; +insert into t1 values(1),(2); +Duplicate entry '2' for key 1 +drop table t1; diff --git a/mysql-test/t/rpl_EE_error.test b/mysql-test/t/rpl_EE_error.test new file mode 100644 index 00000000000..de69c4897c3 --- /dev/null +++ b/mysql-test/t/rpl_EE_error.test @@ -0,0 +1,30 @@ +# See if an EE_ error in one event of the master's binlog stops replication +# (it should not: in this configuration the EE_ error is probably not +# critical). Example: you do a DROP TABLE on a table which has no MYI file +# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and +# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986). + +source include/master-slave.inc; + +create table t1 (a int) type=myisam; +flush tables; +system rm ./var/master-data/test/t1.MYI ; +drop table t1; +save_master_pos; +connection slave; +sync_with_master; + +# Now a real error. + +connection master; +create table t1 (a int, unique(a)) type=myisam; +set sql_log_bin=0; +insert into t1 values(2); +set sql_log_bin=1; +save_master_pos; +--error 1062; +insert into t1 values(1),(2); +drop table t1; +save_master_pos; +connection slave; +wait_for_slave_to_stop; diff --git a/sql/log_event.cc b/sql/log_event.cc index 9779b7401dd..4413a77c364 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1922,7 +1922,7 @@ Default database: '%s'", // assume no convert for next query unless set explictly thd->variables.convert_set = 0; close_thread_tables(thd); - free_root(&thd->mem_root,0); + free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); return (thd->query_error ? thd->query_error : Log_event::exec_event(rli)); } @@ -2094,10 +2094,10 @@ Slave: load data infile on table '%s' at log position %s in log \ slave_print_error(rli,sql_errno,"\ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'", err, (char*)table_name, print_slave_db_safe(db)); - free_root(&thd->mem_root,0); + free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); return 1; } - free_root(&thd->mem_root,0); + free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); if (thd->fatal_error) { diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 03a359d44e7..e8e2f808b7e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1130,6 +1130,7 @@ bool change_password(THD *thd, const char *host, const char *user, acl_user->user ? acl_user->user : "", acl_user->host.hostname ? acl_user->host.hostname : "", new_password)); + thd->clear_error(); mysql_update_log.write(thd, buff, query_length); Query_log_event qinfo(thd, buff, query_length, 0); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e4694adb9a2..cf42109fb9a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -575,8 +575,8 @@ void close_temporary_tables(THD *thd) if (query && found_user_tables && mysql_bin_log.is_open()) { /* The -1 is to remove last ',' */ + thd->clear_error(); Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0); - qinfo.error_code=0; mysql_bin_log.write(&qinfo); } thd->temporary_tables=0; diff --git a/sql/sql_class.h b/sql/sql_class.h index 9287a0c8c79..2899c643536 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -590,6 +590,15 @@ public: void add_changed_table(TABLE *table); void add_changed_table(const char *key, long key_length); CHANGED_TABLE_LIST * changed_table_dup(const char *key, long key_length); +#ifndef EMBEDDED_LIBRARY + inline void clear_error() + { + net.last_error[0]= 0; + net.last_errno= 0; + } +#else + void clear_error(); +#endif }; /* Flags for the THD::system_thread (bitmap) variable */ diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 6251b1ec624..6c11067ac8f 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -86,6 +86,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) 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, 0); mysql_bin_log.write(&qinfo); } @@ -176,6 +177,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) 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, 0); mysql_bin_log.write(&qinfo); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 34a79ecd78d..ef90cd55730 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -175,6 +175,8 @@ cleanup: mysql_update_log.write(thd,thd->query, thd->query_length); if (mysql_bin_log.is_open()) { + if (error <= 0) + thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); if (mysql_bin_log.write(&qinfo) && transactional_table) @@ -479,6 +481,8 @@ bool multi_delete::send_eof() mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { + if (error <= 0) + thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); if (mysql_bin_log.write(&qinfo) && !normal_tables) @@ -591,6 +595,7 @@ end: 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, thd->tmp_table); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3414e76e092..00545f04c44 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -310,6 +310,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { + if (error <= 0) + thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); if (mysql_bin_log.write(&qinfo) && transactional_table) @@ -1196,7 +1198,7 @@ bool delayed_insert::handle_inserts(void) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); using_ignore=1; } - thd.net.last_errno = 0; // reset error for binlog + thd.clear_error(); // reset error for binlog if (write_record(table,&info)) { info.error_count++; // Ignore errors @@ -1391,6 +1393,8 @@ bool select_insert::send_eof() 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, table->file->has_transactions()); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c867112bb2a..9be861cf2c9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2461,6 +2461,7 @@ mysql_execute_command(void) 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, 0); mysql_bin_log.write(&qinfo); } @@ -2481,6 +2482,7 @@ mysql_execute_command(void) 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, 0); mysql_bin_log.write(&qinfo); } diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index d7e998264f3..05d31c173d3 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -82,6 +82,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) 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, 0); mysql_bin_log.write(&qinfo); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 94ecf33b9c6..07fc6971502 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -237,6 +237,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, 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); @@ -779,6 +780,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, 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, test(create_info->options & HA_LEX_CREATE_TMP_TABLE)); @@ -1561,6 +1563,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, 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, 0); mysql_bin_log.write(&qinfo); } @@ -1931,6 +1934,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, 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, 0); mysql_bin_log.write(&qinfo); } @@ -2063,6 +2067,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, 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, 0); mysql_bin_log.write(&qinfo); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d5034644830..74a4c80bfce 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -319,6 +319,8 @@ int mysql_update(THD *thd, mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { + if (error <= 0) + thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); if (mysql_bin_log.write(&qinfo) && transactional_table) @@ -939,6 +941,8 @@ bool multi_update::send_eof() mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) { + if (local_error <= 0) + thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); if (mysql_bin_log.write(&qinfo) && trans_safe) From 56f0abf7bb88c98adc4e65de032f63f40498b834 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Tue, 16 Dec 2003 13:20:17 +0200 Subject: [PATCH 72/89] Portability fixes (mostly test suite) Make ENGINE= an alias for TYPE= (Compabiltiy with 4.1) Fix when using symlinked data files and realpath() is not working --- client/mysqltest.c | 413 ++++++++++++++++--------- include/my_sys.h | 2 +- myisam/mi_check.c | 12 +- mysql-test/r/handler.result | 2 +- mysql-test/r/rpl_max_relay_size.result | 2 +- mysql-test/r/rpl_rotate_logs.result | 11 +- mysql-test/r/rpl_trunc_binlog.result | 2 +- mysql-test/t/handler.test | 2 +- mysql-test/t/rpl_log_pos.test | 2 +- mysql-test/t/rpl_max_relay_size.test | 1 + mysql-test/t/rpl_rotate_logs.test | 9 +- mysql-test/t/rpl_trunc_binlog.test | 1 + mysys/my_symlink.c | 1 + sql/lex.h | 1 + sql/mysqld.cc | 4 +- strings/strto.c | 2 - strings/strtoll.c | 3 +- strings/strtoull.c | 1 - 18 files changed, 288 insertions(+), 183 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index a168099e6d6..e3aa78c05df 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -42,7 +42,7 @@ **********************************************************************/ -#define MTEST_VERSION "1.29" +#define MTEST_VERSION "1.30" #include #include @@ -54,18 +54,15 @@ #include #include #include -#include -#include #include #include #include -#include -#include #include -#define MAX_QUERY 65536 +#define MAX_QUERY 65536 +#define MAX_COLUMNS 256 #define PAD_SIZE 128 -#define MAX_CONS 1024 +#define MAX_CONS 128 #define MAX_INCLUDE_DEPTH 16 #define LAZY_GUESS_BUF_SIZE 8192 #define INIT_Q_LINES 1024 @@ -79,6 +76,11 @@ #endif #define MAX_SERVER_ARGS 20 +/* Defines to make this look like MySQL 4.1 */ +#define charset_info default_charset_info +#define my_isvar(A,B) isvar(B) +#define my_hash_insert(A,B) hash_insert((A), (B)) + /* Sometimes in a test the client starts before the server - to solve the problem, we try again @@ -117,7 +119,6 @@ static FILE** cur_file; static FILE** file_stack_end; static uint lineno_stack[MAX_INCLUDE_DEPTH]; static char TMPDIR[FN_REFLEN]; -static int *block_ok_stack_end; static int *cur_block, *block_stack_end; static int block_stack[BLOCK_STACK_DEPTH]; @@ -135,10 +136,10 @@ static const char *embedded_server_groups[] = { NullS }; -#include "sslopt-vars.h" - DYNAMIC_ARRAY q_lines; +#include "sslopt-vars.h" + typedef struct { char file[FN_REFLEN]; @@ -180,7 +181,8 @@ typedef struct VAR var_reg[10]; /*Perl/shell-like variable registers */ HASH var_hash; -int disable_query_log=0, disable_result_log=0; +my_bool disable_query_log=0, disable_result_log=0, disable_warnings=0; +my_bool disable_info= 1; /* By default off */ struct connection cons[MAX_CONS]; struct connection* cur_con, *next_con, *cons_end; @@ -200,7 +202,7 @@ Q_SYNC_WITH_MASTER, Q_SYNC_SLAVE_WITH_MASTER, Q_ERROR, Q_SEND, Q_REAP, -Q_DIRTY_CLOSE, Q_REPLACE, +Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN, Q_PING, Q_EVAL, Q_RPL_PROBE, Q_ENABLE_RPL_PARSE, Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, @@ -209,6 +211,8 @@ Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER, Q_WAIT_FOR_SLAVE_TO_STOP, Q_REQUIRE_VERSION, +Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, +Q_ENABLE_INFO, Q_DISABLE_INFO, Q_EXEC, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -260,6 +264,7 @@ const char *command_names[]= "reap", "dirty_close", "replace_result", + "replace_column", "ping", "eval", "rpl_probe", @@ -275,6 +280,10 @@ const char *command_names[]= "require_manager", "wait_for_slave_to_stop", "require_version", + "enable_warnings", + "disable_warnings", + "enable_info", + "disable_info", "exec", 0 }; @@ -301,7 +310,7 @@ VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, int eval_expr(VAR* v, const char *p, const char** p_end); static int read_server_arguments(const char *name); -/* Definitions for replace */ +/* Definitions for replace result */ typedef struct st_pointer_array { /* when using array-strings */ TYPELIB typelib; /* Pointer to strings */ @@ -329,6 +338,13 @@ static char *out_buff; static uint out_length; static int eval_result = 0; +/* For column replace */ +char *replace_column[MAX_COLUMNS]; +uint max_replace_column= 0; + +static void get_replace_column(struct st_query *q); +static void free_replace_column(); + /* Disable functions that only exist in MySQL 4.0 */ #if MYSQL_VERSION_ID < 40000 || defined(EMBEDDED_LIBRARY) void mysql_enable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} @@ -339,7 +355,6 @@ int mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, int len); - static void do_eval(DYNAMIC_STRING* query_eval, const char* query) { const char* p; @@ -434,6 +449,7 @@ static void free_used_memory() delete_dynamic(&q_lines); dynstr_free(&ds_res); free_replace(); + free_replace_column(); my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); free_defaults(default_argv); mysql_server_end(); @@ -602,7 +618,7 @@ VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw, { const char* save_var_name = var_name, *end; end = (var_name_end) ? *var_name_end : 0; - while (isvar(*var_name) && var_name != end) + while (my_isvar(charset_info,*var_name) && var_name != end) ++var_name; if (var_name == save_var_name) { @@ -647,7 +663,7 @@ static VAR* var_obtain(char* name, int len) if ((v = (VAR*)hash_search(&var_hash, name, len))) return v; v = var_init(0, name, len, "", 0); - hash_insert(&var_hash, (byte*)v); + my_hash_insert(&var_hash, (byte*)v); return v; } @@ -700,13 +716,13 @@ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) MYSQL* mysql = &cur_con->mysql; for (;;) { - MYSQL_RES* res; + MYSQL_RES *res; MYSQL_ROW row; int done; LINT_INIT(res); - if (mysql_query(mysql,"show status like 'Slave_running'") - || !(res=mysql_store_result(mysql))) + if (mysql_query(mysql,"show status like 'Slave_running'") || + !(res=mysql_store_result(mysql))) die("Query failed while probing slave for stop: %s", mysql_error(mysql)); if (!(row=mysql_fetch_row(res)) || !row[1]) @@ -753,10 +769,8 @@ int do_server_op(struct st_query* q,const char* op) com_p=strmov(com_p,"_exec "); if (!*p) die("Missing server name in server_%s\n",op); - while (*p && !isspace(*p)) - { - *com_p++=*p++; - } + while (*p && !my_isspace(charset_info,*p)) + *com_p++= *p++; *com_p++=' '; com_p=int10_to_str(manager_wait_timeout,com_p,10); *com_p++ = '\n'; @@ -786,7 +800,7 @@ int do_require_version(struct st_query* q) if (!*p) die("Missing version argument in require_version\n"); ver_arg = p; - while (*p && !isspace(*p)) + while (*p && !my_isspace(charset_info,*p)) p++; *p = 0; ver_arg_len = p - ver_arg; @@ -816,7 +830,7 @@ int do_source(struct st_query* q) if (!*p) die("Missing file name in source\n"); name = p; - while (*p && !isspace(*p)) + while (*p && !my_isspace(charset_info,*p)) p++; *p = 0; @@ -848,7 +862,7 @@ int do_exec(struct st_query* q) FILE *res_file; char *cmd= q->first_argument; - while (*cmd && isspace(*cmd)) + while (*cmd && my_isspace(charset_info, *cmd)) cmd++; if (!*cmd) die("Missing argument in exec\n"); @@ -1018,16 +1032,16 @@ int do_system(struct st_query* q) var_init(&v, 0, 0, 0, 0); eval_expr(&v, p, 0); /* NULL terminated */ if (v.str_val_len) - { - char expr_buf[512]; - if ((uint)v.str_val_len > sizeof(expr_buf) - 1) - v.str_val_len = sizeof(expr_buf) - 1; - memcpy(expr_buf, v.str_val, v.str_val_len); - expr_buf[v.str_val_len] = 0; - DBUG_PRINT("info", ("running system command '%s'", expr_buf)); - if (system(expr_buf) && q->abort_on_error) - die("system command '%s' failed", expr_buf); - } + { + char expr_buf[512]; + if ((uint)v.str_val_len > sizeof(expr_buf) - 1) + v.str_val_len = sizeof(expr_buf) - 1; + memcpy(expr_buf, v.str_val, v.str_val_len); + expr_buf[v.str_val_len] = 0; + DBUG_PRINT("info", ("running system command '%s'", expr_buf)); + if (system(expr_buf) && q->abort_on_error) + die("system command '%s' failed", expr_buf); + } var_free(&v); return 0; } @@ -1075,7 +1089,8 @@ int do_sync_with_master2(const char* p) mysql_errno(mysql), mysql_error(mysql)); if (!(last_result = res = mysql_store_result(mysql))) - die("line %u: mysql_store_result() returned NULL", start_lineno); + die("line %u: mysql_store_result() returned NULL for '%s'", start_lineno, + query_buf); if (!(row = mysql_fetch_row(res))) die("line %u: empty result in %s", start_lineno, query_buf); if (!row[0]) @@ -1099,17 +1114,19 @@ int do_save_master_pos() MYSQL_RES* res; MYSQL_ROW row; MYSQL* mysql = &cur_con->mysql; + const char *query; int rpl_parse; rpl_parse = mysql_rpl_parse_enabled(mysql); mysql_disable_rpl_parse(mysql); - if (mysql_query(mysql, "show master status")) + if (mysql_query(mysql, query= "show master status")) die("At line %u: failed in show master status: %d: %s", start_lineno, mysql_errno(mysql), mysql_error(mysql)); if (!(last_result =res = mysql_store_result(mysql))) - die("line %u: mysql_store_result() retuned NULL", start_lineno); + die("line %u: mysql_store_result() retuned NULL for '%s'", start_lineno, + query); if (!(row = mysql_fetch_row(res))) die("line %u: empty result in show master status", start_lineno); strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); @@ -1130,11 +1147,11 @@ int do_let(struct st_query* q) if (!*p) die("Missing variable name in let\n"); var_name = p; - while (*p && (*p != '=' || isspace(*p))) + while (*p && (*p != '=' || my_isspace(charset_info,*p))) p++; var_name_end = p; if (*p == '=') p++; - while (*p && isspace(*p)) + while (*p && my_isspace(charset_info,*p)) p++; var_val_start = p; return var_set(var_name, var_name_end, var_val_start, q->end); @@ -1163,8 +1180,8 @@ int do_disable_rpl_parse(struct st_query* q __attribute__((unused))) int do_sleep(struct st_query* q, my_bool real_sleep) { - char* p=q->first_argument; - while (*p && isspace(*p)) + char *p=q->first_argument; + while (*p && my_isspace(charset_info,*p)) p++; if (!*p) die("Missing argument in sleep\n"); @@ -1180,7 +1197,7 @@ static void get_file_name(char *filename, struct st_query* q) char* p=q->first_argument; strnmov(filename, p, FN_REFLEN); /* Remove end space */ - while (p > filename && isspace(p[-1])) + while (p > filename && my_isspace(charset_info,p[-1])) p--; p[0]=0; } @@ -1266,7 +1283,7 @@ static char *get_string(char **to_ptr, char **from_ptr, if (*from != ' ' && *from) die("Wrong string argument in %s\n", q->query); - while (isspace(*from)) /* Point to next string */ + while (my_isspace(charset_info,*from)) /* Point to next string */ from++; *to =0; /* End of string marker */ @@ -1323,8 +1340,8 @@ static void get_replace(struct st_query *q) insert_pointer_name(&to_array,to); } for (i=1,pos=word_end_chars ; i < 256 ; i++) - if (isspace(i)) - *pos++=i; + if (my_isspace(charset_info,i)) + *pos++= i; *pos=0; /* End pointer */ if (!(glob_replace=init_replace((char**) from_array.typelib.type_names, (char**) to_array.typelib.type_names, @@ -1360,7 +1377,7 @@ int select_connection(char *p) if (!*p) die("Missing connection name in connect\n"); name = p; - while (*p && !isspace(*p)) + while (*p && !my_isspace(charset_info,*p)) p++; *p = 0; @@ -1386,7 +1403,7 @@ int close_connection(struct st_query* q) if (!*p) die("Missing connection name in connect\n"); name = p; - while (*p && !isspace(*p)) + while (*p && !my_isspace(charset_info,*p)) p++; *p = 0; @@ -1394,6 +1411,7 @@ int close_connection(struct st_query* q) { if (!strcmp(con->name, name)) { +#ifndef EMBEDDED_LIBRARY if (q->type == Q_DIRTY_CLOSE) { if (con->mysql.net.vio) @@ -1402,7 +1420,7 @@ int close_connection(struct st_query* q) con->mysql.net.vio = 0; } } - +#endif mysql_close(&con->mysql); DBUG_RETURN(0); } @@ -1422,11 +1440,13 @@ int close_connection(struct st_query* q) char* safe_get_param(char* str, char** arg, const char* msg) { DBUG_ENTER("safe_get_param"); - while (*str && isspace(*str)) str++; + while (*str && my_isspace(charset_info,*str)) + str++; *arg = str; for (; *str && *str != ',' && *str != ')' ; str++) { - if (isspace(*str)) *str = 0; + if (my_isspace(charset_info,*str)) + *str = 0; } if (!*str) die(msg); @@ -1474,7 +1494,6 @@ int do_connect(struct st_query* q) char* p=q->first_argument; char buff[FN_REFLEN]; int con_port; - int con_error; int free_con_sock = 0; DBUG_ENTER("do_connect"); @@ -1539,9 +1558,9 @@ int do_connect(struct st_query* q) /* Special database to allow one to connect without a database name */ if (con_db && !strcmp(con_db,"*NO-ONE*")) con_db=0; - if ((con_error = safe_connect(&next_con->mysql, con_host, - con_user, con_pass, - con_db, con_port, con_sock ? con_sock: 0))) + if ((safe_connect(&next_con->mysql, con_host, + con_user, con_pass, + con_db, con_port, con_sock ? con_sock: 0))) die("Could not open connection '%s': %s", con_name, mysql_error(&next_con->mysql)); @@ -1663,7 +1682,7 @@ int read_line(char* buf, int size) { state = R_COMMENT; } - else if (isspace(c)) + else if (my_isspace(charset_info,c)) { if (c == '\n') start_lineno= ++*lineno; /* Query hasn't started yet */ @@ -1789,7 +1808,7 @@ int read_query(struct st_query** q_ptr) { expected_errno = 0; p++; - for (;isdigit(*p);p++) + for (;my_isdigit(charset_info,*p);p++) expected_errno = expected_errno * 10 + *p - '0'; q->expected_errno[0] = expected_errno; q->expected_errno[1] = 0; @@ -1797,25 +1816,28 @@ int read_query(struct st_query** q_ptr) } } - while (*p && isspace(*p)) p++ ; + while (*p && my_isspace(charset_info,*p)) + p++ ; if (*p == '@') { p++; p1 = q->record_file; - while (!isspace(*p) && + while (!my_isspace(charset_info,*p) && p1 < q->record_file + sizeof(q->record_file) - 1) *p1++ = *p++; *p1 = 0; } } - while (*p && isspace(*p)) p++; + while (*p && my_isspace(charset_info,*p)) + p++; if (!(q->query_buf=q->query=my_strdup(p,MYF(MY_WME)))) die(NullS); /* Calculate first word and first argument */ - for (p=q->query; *p && !isspace(*p) ; p++) ; + for (p=q->query; *p && !my_isspace(charset_info,*p) ; p++) ; q->first_word_len = (uint) (p - q->query); - while (*p && isspace(*p)) p++; + while (*p && my_isspace(charset_info,*p)) + p++; q->first_argument=p; q->end = strend(q->query); parser.read_lines++; @@ -1825,34 +1847,34 @@ int read_query(struct st_query** q_ptr) static struct my_option my_long_options[] = { - {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'", + {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"database", 'D', "Database to use.", (gptr*) &db, (gptr*) &db, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"basedir", 'b', "Basedir for tests", (gptr*) &opt_basedir, + {"basedir", 'b', "Basedir for tests.", (gptr*) &opt_basedir, (gptr*) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"big-test", 'B', "Define BIG_TEST to 1", (gptr*) &opt_big_test, + {"big-test", 'B', "Define BIG_TEST to 1.", (gptr*) &opt_big_test, (gptr*) &opt_big_test, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"compress", 'C', "Use the compressed server/client protocol", + {"compress", 'C', "Use the compressed server/client protocol.", (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"manager-user", OPT_MANAGER_USER, "Undocumented: Used for debugging", + {"manager-user", OPT_MANAGER_USER, "Undocumented: Used for debugging.", (gptr*) &manager_user, (gptr*) &manager_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"manager-host", OPT_MANAGER_HOST, "Undocumented: Used for debugging", + {"manager-host", OPT_MANAGER_HOST, "Undocumented: Used for debugging.", (gptr*) &manager_host, (gptr*) &manager_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"manager-password", OPT_MANAGER_PASSWD, "Undocumented: Used for debugging", + {"manager-password", OPT_MANAGER_PASSWD, "Undocumented: Used for debugging.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"manager-port", OPT_MANAGER_PORT, "Undocumented: Used for debugging", + {"manager-port", OPT_MANAGER_PORT, "Undocumented: Used for debugging.", (gptr*) &manager_port, (gptr*) &manager_port, 0, GET_INT, REQUIRED_ARG, MYSQL_MANAGER_PORT, 0, 0, 0, 0, 0}, {"manager-wait-timeout", OPT_MANAGER_WAIT_TIMEOUT, - "Undocumented: Used for debugging", (gptr*) &manager_wait_timeout, + "Undocumented: Used for debugging.", (gptr*) &manager_wait_timeout, (gptr*) &manager_wait_timeout, 0, GET_INT, REQUIRED_ARG, 3, 0, 0, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -1865,16 +1887,16 @@ static struct my_option my_long_options[] = {"result-file", 'R', "Read/Store result from/in this file.", (gptr*) &result_file, (gptr*) &result_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"server-arg", 'A', "Send enbedded server this as a paramenter", + {"server-arg", 'A', "Send enbedded server this as a paramenter.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"server-file", 'F', "Read embedded server arguments from file", + {"server-file", 'F', "Read embedded server arguments from file.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"silent", 's', "Suppress all normal output. Synonym for --quiet.", (gptr*) &silent, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-safemalloc", OPT_SKIP_SAFEMALLOC, - "Don't use the memory allocation checking", 0, 0, 0, GET_NO_ARG, NO_ARG, + "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"sleep", 'T', "Sleep always this many seconds on sleep commands", + {"sleep", 'T', "Sleep always this many seconds on sleep commands.", (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection.", @@ -1883,7 +1905,7 @@ static struct my_option my_long_options[] = #include "sslopt-longopts.h" {"test-file", 'x', "Read test from/in this file (default stdin).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"tmpdir", 't', "Temporary directory where sockets are put", + {"tmpdir", 't', "Temporary directory where sockets are put.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -1894,7 +1916,6 @@ static struct my_option my_long_options[] = { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; - static void print_version(void) { printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION, @@ -1995,12 +2016,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), int parse_args(int argc, char **argv) { - int ho_error; - load_defaults("my",load_default_groups,&argc,&argv); default_argv= argv; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((handle_options(&argc, &argv, my_long_options, get_one_option))) exit(1); if (argc > 1) @@ -2067,6 +2086,45 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, } +/* + Append all results to the dynamic string separated with '\t' + Values may be converted with 'replace_column' +*/ + +static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) +{ + MYSQL_ROW row; + uint num_fields= mysql_num_fields(res); + unsigned long *lengths; + while ((row = mysql_fetch_row(res))) + { + uint i; + lengths = mysql_fetch_lengths(res); + for (i = 0; i < num_fields; i++) + { + const char *val= row[i]; + ulonglong len= lengths[i]; + + if (i < max_replace_column && replace_column[i]) + { + val= replace_column[i]; + len= strlen(val); + } + if (!val) + { + val= "NULL"; + len= 4; + } + if (i) + dynstr_append_mem(ds, "\t", 1); + replace_dynstr_append_mem(ds, val, len); + } + dynstr_append_mem(ds, "\n", 1); + } + free_replace_column(); +} + + /* * flags control the phased/stages of query execution to be performed * if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on @@ -2076,12 +2134,7 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, int run_query(MYSQL* mysql, struct st_query* q, int flags) { MYSQL_RES* res = 0; - MYSQL_FIELD* fields; - MYSQL_ROW row; - int num_fields,i, error = 0; - unsigned long* lengths; - char* val; - int len; + int i, error = 0; DYNAMIC_STRING *ds; DYNAMIC_STRING ds_tmp; DYNAMIC_STRING eval_query; @@ -2153,33 +2206,31 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) goto end; /* Ok */ } } - if (i) - { - replace_dynstr_append_mem(ds, mysql_error(mysql), - strlen(mysql_error(mysql))); - dynstr_append_mem(ds,"\n",1); - verbose_msg("query '%s' failed with wrong errno %d instead of %d...", - q->query, mysql_errno(mysql), q->expected_errno[0]); - error=1; - goto end; - } - replace_dynstr_append_mem(ds,mysql_error(mysql), + DBUG_PRINT("info",("i: %d expected_errors: %d", i, q->expected_errors)); + replace_dynstr_append_mem(ds, mysql_error(mysql), strlen(mysql_error(mysql))); dynstr_append_mem(ds,"\n",1); + if (i) + { + verbose_msg("query '%s' failed with wrong errno %d instead of %d...", + q->query, mysql_errno(mysql), q->expected_errno[0]); + error= 1; + goto end; + } verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql), mysql_error(mysql)); /* - if we do not abort on error, failure to run the query does - not fail the whole test case + if we do not abort on error, failure to run the query does + not fail the whole test case */ goto end; } /*{ verbose_msg("failed in mysql_store_result for query '%s' (%d)", query, - mysql_errno(mysql)); + mysql_errno(mysql)); error = 1; goto end; - }*/ + }*/ } if (q->expected_errno[0]) @@ -2190,45 +2241,33 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) goto end; } - if (!res) - goto end; - if (!disable_result_log) { - fields = mysql_fetch_fields(res); - num_fields = mysql_num_fields(res); - for (i = 0; i < num_fields; i++) + if (res) { - if (i) - dynstr_append_mem(ds, "\t", 1); - dynstr_append(ds, fields[i].name); - } - - dynstr_append_mem(ds, "\n", 1); - - while ((row = mysql_fetch_row(res))) - { - lengths = mysql_fetch_lengths(res); + int num_fields= mysql_num_fields(res); + MYSQL_FIELD *fields= mysql_fetch_fields(res); for (i = 0; i < num_fields; i++) { - val = (char*)row[i]; - len = lengths[i]; - - if (!val) - { - val = (char*)"NULL"; - len = 4; - } - if (i) dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, len); + dynstr_append(ds, fields[i].name); } dynstr_append_mem(ds, "\n", 1); + append_result(ds, res); + } + + if (!disable_info && mysql_info(mysql)) + { + dynstr_append(ds, "info: "); + dynstr_append(ds, mysql_info(mysql)); + dynstr_append_mem(ds, "\n", 1); } - if (glob_replace) - free_replace(); } + + if (glob_replace) + free_replace(); + if (record) { if (!q->record_file[0] && !result_file) @@ -2273,7 +2312,7 @@ void get_query_type(struct st_query* q) q->type=(enum enum_commands) type; /* Found command */ } -static byte* get_var_key(const byte* var, uint* len, +static byte *get_var_key(const byte* var, uint* len, my_bool __attribute__((unused)) t) { register char* key; @@ -2282,11 +2321,11 @@ static byte* get_var_key(const byte* var, uint* len, return (byte*)key; } -static VAR* var_init(VAR* v, const char* name, int name_len, const char* val, +static VAR *var_init(VAR *v, const char *name, int name_len, const char *val, int val_len) { int val_alloc_len; - VAR* tmp_var; + VAR *tmp_var; if (!name_len && name) name_len = strlen(name); if (!val_len && val) @@ -2302,7 +2341,6 @@ static VAR* var_init(VAR* v, const char* name, int name_len, const char* val, if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME)))) die("Out of memory"); - /* 'name' may be NULL here, but in this case name_len is 0 */ memcpy(tmp_var->name, name, name_len); if (val) { @@ -2317,7 +2355,7 @@ static VAR* var_init(VAR* v, const char* name, int name_len, const char* val, return tmp_var; } -static void var_free(void* v) +static void var_free(void *v) { my_free(((VAR*) v)->str_val, MYF(MY_WME)); if (((VAR*)v)->alloced) @@ -2325,38 +2363,42 @@ static void var_free(void* v) } -static void var_from_env(const char* name, const char* def_val) +static void var_from_env(const char *name, const char *def_val) { - const char* tmp; - VAR* v; + const char *tmp; + VAR *v; if (!(tmp = getenv(name))) tmp = def_val; v = var_init(0, name, 0, tmp, 0); - hash_insert(&var_hash, (byte*)v); + my_hash_insert(&var_hash, (byte*)v); } -static void init_var_hash() +static void init_var_hash(MYSQL *mysql) { - VAR* v; + VAR *v; DBUG_ENTER("init_var_hash"); - if (hash_init(&var_hash, 1024, 0, 0, get_var_key, var_free, MYF(0))) + if (hash_init(&var_hash, + 1024, 0, 0, get_var_key, var_free, MYF(0))) die("Variable hash initialization failed"); var_from_env("MASTER_MYPORT", "9306"); var_from_env("SLAVE_MYPORT", "9307"); var_from_env("MYSQL_TEST_DIR", "/tmp"); var_from_env("BIG_TEST", opt_big_test ? "1" : "0"); - v=var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "63",0); - hash_insert(&var_hash, (byte*)v); + v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0); + my_hash_insert(&var_hash, (byte*) v); + v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0); + my_hash_insert(&var_hash, (byte*) v); + DBUG_VOID_RETURN; } -int main(int argc, char** argv) +int main(int argc, char **argv) { int error = 0; - struct st_query* q; + struct st_query *q; my_bool require_file=0, q_send_flag=0; char save_file[FN_REFLEN]; MY_INIT(argv[0]); @@ -2381,7 +2423,6 @@ int main(int argc, char** argv) memset(block_stack, 0, sizeof(block_stack)); block_stack_end = block_stack + BLOCK_STACK_DEPTH; memset(block_ok_stack, 0, sizeof(block_stack)); - block_ok_stack_end = block_ok_stack + BLOCK_STACK_DEPTH; cur_block = block_stack; block_ok = block_ok_stack; *block_ok = 1; @@ -2391,7 +2432,6 @@ int main(int argc, char** argv) embedded_server_args, (char**) embedded_server_groups)) die("Can't initialize MySQL server"); - init_var_hash(); if (cur_file == file_stack) *++cur_file = stdin; *lineno=1; @@ -2410,14 +2450,14 @@ int main(int argc, char** argv) opt_ssl_capath, opt_ssl_cipher); #endif - cur_con->name = my_strdup("default", MYF(MY_WME)); - if (!cur_con->name) + if (!(cur_con->name = my_strdup("default", MYF(MY_WME)))) die("Out of memory"); - if (safe_connect(&cur_con->mysql, host, - user, pass, db, port, unix_sock)) + if (safe_connect(&cur_con->mysql, host, user, pass, db, port, unix_sock)) die("Failed in mysql_real_connect(): %s", mysql_error(&cur_con->mysql)); + init_var_hash(&cur_con->mysql); + while (!read_query(&q)) { int current_line_inc = 1, processed = 0; @@ -2439,6 +2479,10 @@ int main(int argc, char** argv) case Q_DISABLE_QUERY_LOG: disable_query_log=1; break; case Q_ENABLE_RESULT_LOG: disable_result_log=0; break; case Q_DISABLE_RESULT_LOG: disable_result_log=1; break; + case Q_ENABLE_WARNINGS: disable_warnings=0; break; + case Q_DISABLE_WARNINGS: disable_warnings=1; break; + case Q_ENABLE_INFO: disable_info=0; break; + case Q_DISABLE_INFO: disable_info=1; break; case Q_SOURCE: do_source(q); break; case Q_SLEEP: do_sleep(q, 0); break; case Q_REAL_SLEEP: do_sleep(q, 1); break; @@ -2515,6 +2559,9 @@ int main(int argc, char** argv) case Q_REPLACE: get_replace(q); break; + case Q_REPLACE_COLUMN: + get_replace_column(q); + break; case Q_SAVE_MASTER_POS: do_save_master_pos(); break; case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break; case Q_SYNC_SLAVE_WITH_MASTER: @@ -2565,7 +2612,8 @@ int main(int argc, char** argv) } dynstr_free(&ds_res); - if (!silent) { + if (!silent) + { if (error) printf("not ok\n"); else @@ -2584,7 +2632,7 @@ int main(int argc, char** argv) */ -static int read_server_arguments(const char* name) +static int read_server_arguments(const char *name) { char argument[1024],buff[FN_REFLEN], *str=0; FILE *file; @@ -3336,3 +3384,60 @@ static void free_replace_buffer(void) { my_free(out_buff,MYF(MY_WME)); } + + +/**************************************************************************** + Replace results for a column +*****************************************************************************/ + +static void free_replace_column() +{ + uint i; + for (i=0 ; i < max_replace_column ; i++) + { + if (replace_column[i]) + { + my_free(replace_column[i], 0); + replace_column[i]= 0; + } + } + max_replace_column= 0; +} + +/* + Get arguments for replace_columns. The syntax is: + replace-column column_number to_string [column_number to_string ...] + Where each argument may be quoted with ' or " + A argument may also be a variable, in which case the value of the + variable is replaced. +*/ + +static void get_replace_column(struct st_query *q) +{ + char *from=q->first_argument; + char *buff,*start; + DBUG_ENTER("get_replace_columns"); + + free_replace_column(); + if (!*from) + die("Missing argument in %s\n", q->query); + + /* Allocate a buffer for results */ + start=buff=my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); + while (*from) + { + char *to; + uint column_number; + + to= get_string(&buff, &from, q); + if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS) + die("Wrong column number to replace_columns in %s\n", q->query); + if (!*from) + die("Wrong number of arguments to replace in %s\n", q->query); + to= get_string(&buff, &from, q); + my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR); + replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE)); + set_if_bigger(max_replace_column, column_number); + } + my_free(start, MYF(0)); +} diff --git a/include/my_sys.h b/include/my_sys.h index acb4c01b4f1..e1656cfc626 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -167,7 +167,7 @@ extern char *my_strdup_with_length(const byte *from, uint length, #if defined(_AIX) && !defined(__GNUC__) #pragma alloca #endif /* _AIX */ -#if defined(__GNUC__) && !defined(HAVE_ALLOCA_H) +#if defined(__GNUC__) && !defined(HAVE_ALLOCA_H) && ! defined(alloca) #define alloca __builtin_alloca #endif /* GNUC */ #define my_alloca(SZ) alloca((size_t) (SZ)) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 4ec6d6f6a7c..38e48eb5e06 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1188,9 +1188,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, if (!rep_quick) { /* Get real path for data file */ - fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32); if ((new_file=my_raid_create(fn_format(param->temp_filename, - param->temp_filename,"", + share->data_file_name, "", DATA_TMP_EXT, 2+4), 0,param->tmpfile_createflag, share->base.raid_type, @@ -1861,11 +1860,9 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, if (!rep_quick) { /* Get real path for data file */ - fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32); if ((new_file=my_raid_create(fn_format(param->temp_filename, - param->temp_filename, "", - DATA_TMP_EXT, - 2+4), + share->data_file_name, "", + DATA_TMP_EXT, 2+4), 0,param->tmpfile_createflag, share->base.raid_type, share->base.raid_chunks, @@ -2225,9 +2222,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, if (!rep_quick) { /* Get real path for data file */ - fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32); if ((new_file=my_raid_create(fn_format(param->temp_filename, - param->temp_filename, "", + share->data_file_name, "", DATA_TMP_EXT, 2+4), 0,param->tmpfile_createflag, diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 4af38807518..5467ea6dec2 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -142,7 +142,7 @@ insert into t1 values (17); handler t2 read first; Unknown table 't2' in HANDLER handler t1 open as t2; -alter table t1 type=MyISAM; +alter table t1 engine=MyISAM; handler t2 read first; Unknown table 't2' in HANDLER drop table t1; diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result index 1fa3fcd1adb..d74bc80c0ab 100644 --- a/mysql-test/r/rpl_max_relay_size.result +++ b/mysql-test/r/rpl_max_relay_size.result @@ -26,7 +26,7 @@ select @@global.max_relay_log_size; start slave; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 9457 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 # stop slave; reset slave; set global max_relay_log_size=0; diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index 07490744d81..3ab6af6b631 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -16,13 +16,12 @@ create table t1 (s text); insert into t1 values('Could not break slave'),('Tried hard'); show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 60 master-bin.001 417 slave-relay-bin.001 458 master-bin.001 Yes Yes 0 0 417 458 +127.0.0.1 root MASTER_PORT 60 master-bin.001 417 slave-relay-bin.001 458 master-bin.001 Yes Yes 0 0 417 # select * from t1; s Could not break slave Tried hard flush logs; -drop table if exists t2; create table t2(m int not null auto_increment primary key); insert into t2 values (34),(67),(123); flush logs; @@ -48,7 +47,7 @@ master-bin.003 insert into t2 values (65); show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 60 master-bin.003 290 slave-relay-bin.001 1073 master-bin.003 Yes Yes 0 0 290 1073 +127.0.0.1 root MASTER_PORT 60 master-bin.003 290 slave-relay-bin.001 1073 master-bin.003 Yes Yes 0 0 290 # select * from t2; m 34 @@ -58,8 +57,10 @@ m 1234 create temporary table temp_table (a char(80) not null); insert into temp_table values ("testing temporary tables part 2"); -drop table if exists t3; create table t3 (n int); +select count(*) from t3 where n >= 4; +count(*) +100 create table t4 select * from temp_table; show master logs; Log_name @@ -73,7 +74,7 @@ a testing temporary tables part 2 show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 60 master-bin.004 2886 slave-relay-bin.001 7870 master-bin.004 Yes Yes 0 0 2886 7870 +127.0.0.1 root MASTER_PORT 60 master-bin.004 2886 slave-relay-bin.001 7870 master-bin.004 Yes Yes 0 0 2886 # lock tables t3 read; select count(*) from t3 where n >= 4; count(*) diff --git a/mysql-test/r/rpl_trunc_binlog.result b/mysql-test/r/rpl_trunc_binlog.result index eb5dcf7c593..272fa210807 100644 --- a/mysql-test/r/rpl_trunc_binlog.result +++ b/mysql-test/r/rpl_trunc_binlog.result @@ -10,4 +10,4 @@ reset slave; start slave; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.002 4 slave-relay-bin.002 161 master-bin.001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 317 +127.0.0.1 root MASTER_PORT 1 master-bin.002 4 slave-relay-bin.002 161 master-bin.001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 # diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index 737b220c805..736091a52a9 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -75,7 +75,7 @@ insert into t1 values (17); --error 1109 handler t2 read first; handler t1 open as t2; -alter table t1 type=MyISAM; +alter table t1 engine=MyISAM; --error 1109 handler t2 read first; drop table t1; diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test index e11ba92cfa7..859180d4e25 100644 --- a/mysql-test/t/rpl_log_pos.test +++ b/mysql-test/t/rpl_log_pos.test @@ -23,9 +23,9 @@ sleep 5; show slave status; slave stop; change master to master_log_pos=173; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT slave start; sleep 2; +--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT show slave status; connection master; show master status; diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test index a2167b1ef36..7e9a8a1872e 100644 --- a/mysql-test/t/rpl_max_relay_size.test +++ b/mysql-test/t/rpl_max_relay_size.test @@ -37,6 +37,7 @@ select @@global.max_relay_log_size; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_column 18 # show slave status; stop slave; reset slave; diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index c4dc5de38da..70366fc1749 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -50,11 +50,11 @@ save_master_pos; connection slave; sync_with_master; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_column 18 # show slave status; select * from t1; connection master; flush logs; -drop table if exists t2; create table t2(m int not null auto_increment primary key); insert into t2 values (34),(67),(123); flush logs; @@ -102,6 +102,7 @@ save_master_pos; connection slave; sync_with_master; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_column 18 # show slave status; select * from t2; @@ -113,7 +114,7 @@ connection master; create temporary table temp_table (a char(80) not null); insert into temp_table values ("testing temporary tables part 2"); let $1=100; -drop table if exists t3; + create table t3 (n int); disable_query_log; while ($1) @@ -123,17 +124,17 @@ while ($1) dec $1; } enable_query_log; +select count(*) from t3 where n >= 4; create table t4 select * from temp_table; show master logs; show master status; save_master_pos; connection slave; -#slave stop; -#slave start; sync_with_master; select * from t4; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_column 18 # show slave status; # because of concurrent insert, the table may not be up to date # if we do not lock diff --git a/mysql-test/t/rpl_trunc_binlog.test b/mysql-test/t/rpl_trunc_binlog.test index 2c34b7a442f..98138b61ab7 100644 --- a/mysql-test/t/rpl_trunc_binlog.test +++ b/mysql-test/t/rpl_trunc_binlog.test @@ -21,4 +21,5 @@ start slave; # can't sync_with_master so we must sleep sleep 3; --replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 18 # show slave status; diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index abef0096e28..b366678769e 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -72,6 +72,7 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags) #else int result; DBUG_ENTER("my_symlink"); + DBUG_PRINT("enter",("content: %s linkname: %s", content, linkname)); result= 0; if (symlink(content, linkname)) diff --git a/sql/lex.h b/sql/lex.h index 3bbe1da185e..10ba11f2169 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -131,6 +131,7 @@ static SYMBOL symbols[] = { { "DYNAMIC", SYM(DYNAMIC_SYM),0,0}, { "END", SYM(END),0,0}, { "ELSE", SYM(ELSE),0,0}, + { "ENGINE", SYM(TYPE_SYM),0,0}, /* Alias for TYPE= */ { "ESCAPE", SYM(ESCAPE_SYM),0,0}, { "ESCAPED", SYM(ESCAPED),0,0}, { "ENABLE", SYM(ENABLE_SYM),0,0}, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1bdb2300aba..cc17b4e97fd 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2593,8 +2593,8 @@ int main(int argc, char **argv) { char file_path[FN_REFLEN]; my_path(file_path, argv[0], ""); /* Find name in path */ - fn_format(file_path,argv[0],file_path,"",MY_REPLACE_DIR+ - MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS); + fn_format(file_path,argv[0],file_path,"", + MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS); if (argc == 2) { if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME, diff --git a/strings/strto.c b/strings/strto.c index bd0c8e38fde..c98b19a7e67 100644 --- a/strings/strto.c +++ b/strings/strto.c @@ -35,8 +35,6 @@ it can be compiled with the UNSIGNED and/or LONGLONG flag set */ -#define strtoll glob_strtoll /* Fix for True64 */ - #include #include "m_string.h" #include "m_ctype.h" diff --git a/strings/strtoll.c b/strings/strtoll.c index 8d0ba21d576..b0b4ef328fc 100644 --- a/strings/strtoll.c +++ b/strings/strtoll.c @@ -16,8 +16,9 @@ /* This is defines strtoll() if neaded */ +#define strtoll glob_strtoll /* Fix for True64 */ + #include -#include #if !defined(HAVE_STRTOLL) && defined(HAVE_LONG_LONG) #define USE_LONGLONG #include "strto.c" diff --git a/strings/strtoull.c b/strings/strtoull.c index 25201e546ce..f4f3ce19bf7 100644 --- a/strings/strtoull.c +++ b/strings/strtoull.c @@ -17,7 +17,6 @@ /* This is defines strtoull() */ #include -#include #if !defined(HAVE_STRTOULL) && defined(HAVE_LONG_LONG) #define USE_UNSIGNED #define USE_LONGLONG From 30e318311b35b109d230f7184fe0be1b6e29f02b Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Tue, 16 Dec 2003 14:40:57 +0200 Subject: [PATCH 73/89] Fixes for last pull --- libmysqld/lib_sql.cc | 6 ++++++ sql/field.cc | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 91a308ecb21..2c54603ea7a 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -277,6 +277,12 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, } +void THD::clear_error() +{ + net.last_error[0]= 0; + net.last_errno= 0; +} + /* Make a copy of array and the strings array points to */ diff --git a/sql/field.cc b/sql/field.cc index 05779a312d8..feab607400c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2589,7 +2589,7 @@ void Field_timestamp::store(longlong nr) { long not_used; - if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR) + if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR-1) { current_thd->cuted_fields++; timestamp=0; From a41f9de0d270ab416af13744b6aa01746d15c8d1 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 16 Dec 2003 14:43:34 +0200 Subject: [PATCH 74/89] A new better test case for bug #2128 involving overflow in decimal type with prepended zero's. --- mysql-test/r/type_decimal.result | 195 ++++++++++++++++++++++++++++++- mysql-test/t/type_decimal.test | 15 ++- 2 files changed, 205 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index df5402c89a8..5268ff3696b 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -363,9 +363,198 @@ CREATE TABLE t1 (a_dec DECIMAL(-2,1)); Too big column length for column 'a_dec' (max = 255). Use BLOB instead CREATE TABLE t1 (a_dec DECIMAL(-1,1)); Too big column length for column 'a_dec' (max = 255). Use BLOB instead -create table t1(a decimal(10,4)); -insert into t1 values ("+0000100000000"); +create table t1(a decimal(7,3)); +insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); select * from t1; a -9999999.9999 +1.000 ++1.000 +-1.000 +00001.000 ++0001.000 +-0001.000 +10.000 ++10.000 +-10.000 +00010.000 ++0010.000 +-0010.000 +100.000 ++100.000 +-100.000 +00100.000 ++0100.000 +-0100.000 +1000.000 ++1000.000 +-1000.000 +01000.000 ++1000.000 +-1000.000 +10000.000 +10000.000 +-9999.999 +10000.000 +10000.000 +-9999.999 +99999.999 +99999.999 +-9999.999 +99999.999 +99999.999 +-9999.999 +99999.999 +99999.999 +-9999.999 +99999.999 +99999.999 +-9999.999 +99999.999 +99999.999 +-9999.999 +99999.999 +99999.999 +-9999.999 +99999.999 +99999.999 +-9999.999 +99999.999 +99999.999 +-9999.999 +99999.999 +99999.999 +-9999.999 +99999.999 +99999.999 +-9999.999 +drop table t1; +create table t1(a decimal(7,3) unsigned); +insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); +select * from t1; +a +1.000 ++1.000 +0.000 +0001.000 ++001.000 +0.000 +10.000 ++10.000 +0.000 +0010.000 ++010.000 +0.000 +100.000 ++100.000 +0.000 +0100.000 ++100.000 +0.000 +1000.000 +1000.000 +0.000 +1000.000 +1000.000 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +9999.999 +9999.999 +0.000 +drop table t1; +create table t1(a decimal(7,3) zerofill); +insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); +select * from t1; +a +0001.000 +0001.000 +0000.000 +0001.000 +0001.000 +0000.000 +0010.000 +0010.000 +0000.000 +0010.000 +0010.000 +0000.000 +0100.000 +0100.000 +0000.000 +0100.000 +0100.000 +0000.000 +1000.000 +1000.000 +0000.000 +1000.000 +1000.000 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 +9999.999 +9999.999 +0000.000 drop table t1; diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 14d9625710b..82e53e7bde6 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -241,8 +241,19 @@ CREATE TABLE t1 (a_dec DECIMAL(-2,1)); --error 1074 CREATE TABLE t1 (a_dec DECIMAL(-1,1)); +# # Zero prepend overflow bug -create table t1(a decimal(10,4)); -insert into t1 values ("+0000100000000"); +# + +create table t1(a decimal(7,3)); +insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); +select * from t1; +drop table t1; +create table t1(a decimal(7,3) unsigned); +insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); +select * from t1; +drop table t1; +create table t1(a decimal(7,3) zerofill); +insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); select * from t1; drop table t1; From 989b4ad241a590f2e141607e15debc520d092e30 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Tue, 16 Dec 2003 14:43:34 +0100 Subject: [PATCH 75/89] - Bugfix for Do-rpm (moving of the resulting packages did not work due to a missing space) - Define the subject of the failure mail reports within the calling script instead of logger.pm --- Build-tools/Bootstrap | 2 ++ Build-tools/Do-rpm | 4 +++- Build-tools/logger.pm | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index 7d3ac1322f4..930d053b113 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -99,6 +99,8 @@ if (defined $opt_build_command) print_help("") if ($opt_help); defined($REPO=$ARGV[0]) || print_help("Please enter the BK repository to be used!"); +$subject= "Bootstrap of $REPO failed" if $opt_mail; + &logger("Starting build"); &abort("The directory \"$REPO\" could not be found!") if (!-d $REPO); &logger("Using $REPO as the BK parent repository"); diff --git a/Build-tools/Do-rpm b/Build-tools/Do-rpm index cedd55d1405..a216a3ba5dc 100755 --- a/Build-tools/Do-rpm +++ b/Build-tools/Do-rpm @@ -67,6 +67,8 @@ else die "ERROR: $LOGGER cannot be found!\n"; } +$subject= "RPM build for $SPECFILE failed" if $opt_mail; + # Open the spec file and extract the version number open(SPEC, $SPECFILE) or &abort("Unable to open \"$ARGV[0]\": $!"); @spec= ; @@ -192,7 +194,7 @@ $command.= "$SRCRPMDIR/MySQL*$VERSION*.src.rpm $PWD"; $command= "mv"; $command.= " -v " if ($opt_verbose); -$command.= "$RPMDIR/$RPMARCH/MySQL*$VERSION*.$RPMARCH.rpm $PWD"; +$command.= " $RPMDIR/$RPMARCH/MySQL*$VERSION*.$RPMARCH.rpm $PWD"; &logger("Moving binary RPMs to current dir."); &run_command($command, "Error moving binary RPMs!"); diff --git a/Build-tools/logger.pm b/Build-tools/logger.pm index becde95df18..835d8014aa0 100644 --- a/Build-tools/logger.pm +++ b/Build-tools/logger.pm @@ -53,7 +53,6 @@ sub abort if ($opt_mail && !$opt_dry_run) { $messagefile= "/tmp/message.$$"; - $subject= "Bootstrap of $REPO failed"; open(TMP,">$messagefile"); print TMP "$message\n\n"; close TMP; From 8caa18f9e36898cd15a0e61bbbe3765aeb520e81 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Tue, 16 Dec 2003 17:44:51 +0100 Subject: [PATCH 76/89] - bumped up version number to 4.0.18, now that 4.0.17 has been tagged/released - tagged ChangeSet@1.1655.1.3 as mysql-4.0.17 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 7260a21428d..fd9f6a4f721 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.0.17) +AM_INIT_AUTOMAKE(mysql, 4.0.18) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From b6e55207f58e3251001ab9d6b4ba81dc72d4443a Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Tue, 16 Dec 2003 21:52:11 +0100 Subject: [PATCH 77/89] Fix for BUG#2121 "Inadequate message "check permissions on master.info"": more general message when slave can't start because of incorrect replication information, the previous one was sometimes a misleading indication (i.e. sometimes the problem had nothing to do with system permissions). The perfect fix would be to report the exact error to the client (instead of pointing the client to the error log); this is a bit of work so it's more a development task: WL#1088 "Move all hardcoded messages of replication to share/errmsg.txt". I was not able to modify the errmsg.txt in these sql/ subdirectories: danish dutch german italian portuguese russian spanish swedish ukrainian --- mysql-test/r/rpl_rotate_logs.result | 6 +++--- sql/share/czech/errmsg.txt | 2 +- sql/share/english/errmsg.txt | 2 +- sql/share/estonian/errmsg.txt | 2 +- sql/share/french/errmsg.txt | 2 +- sql/share/greek/errmsg.txt | 2 +- sql/share/hungarian/errmsg.txt | 2 +- sql/share/japanese/errmsg.txt | 2 +- sql/share/korean/errmsg.txt | 2 +- sql/share/norwegian-ny/errmsg.txt | 2 +- sql/share/norwegian/errmsg.txt | 2 +- sql/share/polish/errmsg.txt | 2 +- sql/share/romanian/errmsg.txt | 2 +- sql/share/slovak/errmsg.txt | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index 07490744d81..365ce7d42d3 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -1,11 +1,11 @@ drop table if exists t1, t2, t3, t4; drop table if exists t1, t2, t3, t4; slave start; -Could not initialize master info structure, check permisions on master.info +Could not initialize master info structure, more error messages can be found in the MySQL error log slave start; -Could not initialize master info structure, check permisions on master.info +Could not initialize master info structure, more error messages can be found in the MySQL error log change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; -Could not initialize master info structure, check permisions on master.info +Could not initialize master info structure, more error messages can be found in the MySQL error log reset slave; change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; reset master; diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 72a593cf5f7..069ee4540a3 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -211,7 +211,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 0ce90ac0dab..195ea4b0d00 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -202,7 +202,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 38b45c1443b..6acb6a2ee77 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -207,7 +207,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "Kasutajal %-.64s on juba rohkem ühendusi kui lubatud 'max_user_connections' muutujaga", "Ainult konstantsed suurused on lubatud SET klauslis", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index df2be2803b4..e53352472b9 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -202,7 +202,7 @@ "Cette opération ne peut être réalisée avec un esclave actif, faites SLAVE STOP d'abord", "Cette opération nécessite un esclave actif, configurez les esclaves et faites SLAVE START", "Le server n'est pas configuré comme un esclave, changez le fichier de configuration ou utilisez CHANGE MASTER TO", -"Impossible d'initialiser les structures d'information de maître, vérifiez les permissions sur master.info", +"Impossible d'initialiser les structures d'information de maître, vous trouverez des messages d'erreur supplémentaires dans le journal des erreurs de MySQL", "Impossible de créer une tâche esclave, vérifiez les ressources système", "L'utilisateur %-.64s possède déjà plus de 'max_user_connections' connections actives", "Seules les expressions constantes sont autorisées avec SET", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index e3778aaac10..c7575277508 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -202,7 +202,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 85ea5c2e742..7b65da7a03f 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -204,7 +204,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index f99d262a689..bfd9d607806 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -204,7 +204,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 2a7e03b026d..7a384bb7a6f 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -202,7 +202,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index e6ec84e98a0..1bee058a50b 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -204,7 +204,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index fe379261151..6b92a6da2c4 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -204,7 +204,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index a300dc1e2ab..e963a655245 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -206,7 +206,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index bf1306cd332..436f7395556 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -206,7 +206,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index b9970465871..28e4ca9ddca 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -210,7 +210,7 @@ "This operation cannot be performed with a running slave, run SLAVE STOP first", "This operation requires a running slave, configure slave and do SLAVE START", "The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", +"Could not initialize master info structure, more error messages can be found in the MySQL error log", "Could not create slave thread, check system resources", "User %-.64s has already more than 'max_user_connections' active connections", "You may only use constant expressions with SET", From 680b2ee4343bbbf03a490ccf9c97df0a628f2579 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Wed, 17 Dec 2003 18:12:59 +0100 Subject: [PATCH 78/89] Fixed typo. Affected INSERT DELAYED ... SELECT commands --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 50e515d7179..5c08127bfdc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1990,7 +1990,7 @@ mysql_execute_command(void) } /* Fix lock for first table */ if (tables->lock_type == TL_WRITE_DELAYED) - tables->lock_type == TL_WRITE; + tables->lock_type= TL_WRITE; /* Don't unlock tables until command is written to binary log */ select_lex->options|= SELECT_NO_UNLOCK; From 7aad55d97dabef3c35b3028ffc96cca5254d563c Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Wed, 17 Dec 2003 13:15:01 -0400 Subject: [PATCH 79/89] fixed small error in types in sql/field.cc (char * -> const char*) --- sql/field.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/field.cc b/sql/field.cc index 43244a2f8a6..9d191fb61dc 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4721,7 +4721,7 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)), { uint tmp=(uint) Field_enum::val_int(); if (!tmp || tmp > typelib->count) - val_ptr->set((char*)"",0); + val_ptr->set((const char*)"",0); else val_ptr->set((const char*) typelib->type_names[tmp-1], (uint) strlen(typelib->type_names[tmp-1])); From 508d5e5b9d31abbdf0e38732b420c293753af3d6 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Wed, 17 Dec 2003 23:29:11 +0100 Subject: [PATCH 80/89] Fix for BUG#2145 "mysqld becomes unreliable if unable to create a relay log when replic starts": release the mutex before exiting the function, or it will be kept forever (=> START SLAVE, STOP SLAVE, etc will hang). --- sql/slave.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/slave.cc b/sql/slave.cc index 25eeb34e3a7..116d602b238 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1321,6 +1321,7 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) 1 /* no auto events */, max_relay_log_size ? max_relay_log_size : max_binlog_size)) { + pthread_mutex_unlock(&rli->data_lock); sql_print_error("Failed in open_log() called from init_relay_log_info()"); DBUG_RETURN(1); } From 6e58a7c49ed39b691bbe6279d7034150f04191b0 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 18 Dec 2003 01:13:52 +0200 Subject: [PATCH 81/89] Code cleanup --- client/mysql.cc | 7 +++++-- sql/field.cc | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 370213d4fc4..15770d2eb52 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2228,8 +2228,11 @@ static int sql_real_connect(char *host,char *database,char *user,char *password, uint silent) { - mysql_close(&mysql); - connected= 0; + if (connected) + { + connected= 0; + mysql_close(&mysql); + } mysql_init(&mysql); if (opt_connect_timeout) { diff --git a/sql/field.cc b/sql/field.cc index fd0bea83a05..8bcbf8ecc56 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4721,7 +4721,7 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)), { uint tmp=(uint) Field_enum::val_int(); if (!tmp || tmp > typelib->count) - val_ptr->set((const char*)"",0); + val_ptr->set("",0); else val_ptr->set((const char*) typelib->type_names[tmp-1], (uint) strlen(typelib->type_names[tmp-1])); From b9d8f108c1ea26889be3076983dc7c4ed7768fbd Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 18 Dec 2003 14:40:19 +0200 Subject: [PATCH 82/89] Simple cleanups --- mysql-test/t/auto_increment.test | 2 +- sql/opt_range.cc | 1 - sql/sql_select.cc | 56 +++++++++++++++----------------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index 8c614131684..c26983b5eec 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -82,7 +82,7 @@ insert into t1 values (NULL); select * from t1; drop table t1; -create table t1 (a int not null auto_increment primary key) /*!41002 type=heap */; +create table t1 (a int not null auto_increment primary key) /*!40102 type=heap */; insert into t1 values (NULL); insert into t1 values (-1); select last_insert_id(); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 74e3f855db7..7e5ca50d349 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1076,7 +1076,6 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, all rows between 'X' and 'X ...' */ uint length= uint2korr(str+maybe_null); - char *end; str2= str+ key_part->part_length + maybe_null; /* remove end space */ while (length > 0 && str[length+HA_KEY_BLOB_LENGTH+maybe_null-1] == ' ') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 45defba4a94..1d7187824fe 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1771,41 +1771,37 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, uint tables, COND *cond, table_map normal_tables) { uint and_level,i,found_eq_constant; + KEY_FIELD *key_fields, *end, *field; + if (!(key_fields=(KEY_FIELD*) + thd->alloc(sizeof(key_fields[0])*(thd->cond_count+1)*2))) + return TRUE; /* purecov: inspected */ + and_level=0; field=end=key_fields; + if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64)) + return TRUE; + if (cond) { - KEY_FIELD *key_fields,*end; - KEY_FIELD *field; - - if (!(key_fields=(KEY_FIELD*) - thd->alloc(sizeof(key_fields[0])*(thd->cond_count+1)*2))) - return TRUE; /* purecov: inspected */ - and_level=0; field=end=key_fields; - if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64)) - return TRUE; - if (cond) - { - add_key_fields(join_tab,&end,&and_level,cond,normal_tables); - for (; field != end ; field++) - { - add_key_part(keyuse,field); - /* Mark that we can optimize LEFT JOIN */ - if (field->val->type() == Item::NULL_ITEM && - !field->field->real_maybe_null()) - field->field->table->reginfo.not_exists_optimize=1; - } - } - for (i=0 ; i < tables ; i++) - { - if (join_tab[i].on_expr) - { - add_key_fields(join_tab,&end,&and_level,join_tab[i].on_expr, - join_tab[i].table->map); - } - } - /* fill keyuse with found key parts */ + add_key_fields(join_tab,&end,&and_level,cond,normal_tables); for (; field != end ; field++) + { add_key_part(keyuse,field); + /* Mark that we can optimize LEFT JOIN */ + if (field->val->type() == Item::NULL_ITEM && + !field->field->real_maybe_null()) + field->field->table->reginfo.not_exists_optimize=1; + } } + for (i=0 ; i < tables ; i++) + { + if (join_tab[i].on_expr) + { + add_key_fields(join_tab,&end,&and_level,join_tab[i].on_expr, + join_tab[i].table->map); + } + } + /* fill keyuse with found key parts */ + for (; field != end ; field++) + add_key_part(keyuse,field); if (thd->lex.select->ftfunc_list.elements) { From 1f997d4a701ff5da362e3b584f0e41a326fdd6d4 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 18 Dec 2003 15:24:21 +0200 Subject: [PATCH 83/89] Removed compiler warning Fixed not updated test from last changeset --- mysql-test/r/auto_increment.result | 2 +- sql/mysqld.cc | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index cbd2d48b38d..2d6b058d9c5 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -118,7 +118,7 @@ a 1 2 drop table t1; -create table t1 (a int not null auto_increment primary key) /*!41002 type=heap */; +create table t1 (a int not null auto_increment primary key) /*!40102 type=heap */; insert into t1 values (NULL); insert into t1 values (-1); select last_insert_id(); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index cc17b4e97fd..a4e59c399e5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5136,9 +5136,10 @@ static void create_pid_file() if ((file = my_create(pidfile_name,0664, O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0) { - char buff[21]; - sprintf(buff,"%lu\n",(ulong) getpid()); - (void) my_write(file, buff,strlen(buff),MYF(MY_WME)); + char buff[21], *end; + end= int2str((long) getpid(), buff, 10); + *end++= '\n'; + (void) my_write(file, (byte*) buff, (uint) (end-buff),MYF(MY_WME)); (void) my_close(file, MYF(0)); } } From aa3f200c031913313d5373032a03709635bf0227 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 18 Dec 2003 16:50:01 +0200 Subject: [PATCH 84/89] Fixed that lower_case_table_names is set to 1 for case insensitive file systems. --- sql/mysqld.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a4e59c399e5..a58f3b973ac 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4955,7 +4955,8 @@ static void fix_paths(void) if (!lower_case_table_names && test_if_case_insensitive(mysql_real_data_home) == 1) { - sql_print_error("Warning: Setting lower_case_table_names=1 becasue file system %s is case insensitve", mysql_real_data_home); + sql_print_error("Warning: Setting lower_case_table_names=1 becasue file system %s is case insensitive", mysql_real_data_home); + lower_case_table_names= 1; } } From 33ca68a205ef81dc6592e535d1b403258aa5a4dd Mon Sep 17 00:00:00 2001 From: "ram@gw.mysql.r18.ru" <> Date: Fri, 19 Dec 2003 14:12:29 +0400 Subject: [PATCH 85/89] MYSQL_UNIVERSAL_CLIENT_CHARSET definition has been added. --- client/mysqldump.c | 6 +----- include/my_global.h | 6 ++++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 5c3fa44e30b..af47b7c6955 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -89,11 +89,7 @@ static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, *where=0, *opt_compatible_mode_str= 0, *err_ptr= 0; -#ifdef HAVE_CHARSET_utf8 -static char *default_charset= (char*) "utf8"; -#else -static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; -#endif +static char *default_charset= (char*) MYSQL_UNIVERSAL_CLIENT_CHARSET; static ulong opt_compatible_mode= 0; static uint opt_mysql_port= 0, err_len= 0; static my_string opt_mysql_unix_port=0; diff --git a/include/my_global.h b/include/my_global.h index b5b78774e91..d74a66e9ab9 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1144,4 +1144,10 @@ typedef union { #endif #endif +#ifdef HAVE_CHARSET_utf8 +#define MYSQL_UNIVERSAL_CLIENT_CHARSET "utf8" +#else +#define MYSQL_UNIVERSAL_CLIENT_CHARSET MYSQL_DEFAULT_CHARSET_NAME +#endif + #endif /* my_global_h */ From 0605ab2edb3b0272f92384b5fd1867611c7d2145 Mon Sep 17 00:00:00 2001 From: "lenz@kallisto.local" <> Date: Fri, 19 Dec 2003 12:47:10 +0100 Subject: [PATCH 86/89] - removed empty file mysql-test/t/rpl_temporary-master.opt --- mysql-test/t/rpl_temporary-master.opt | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 mysql-test/t/rpl_temporary-master.opt diff --git a/mysql-test/t/rpl_temporary-master.opt b/mysql-test/t/rpl_temporary-master.opt deleted file mode 100644 index e69de29bb2d..00000000000 From 031390a9a4904924c21929314dcd42886c84c175 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Fri, 19 Dec 2003 16:25:50 +0200 Subject: [PATCH 87/89] Fixes after merge with 4.0 Cleaned up embedded library access and query cache handling Changed min stack size to 128K (to allow longer MyISAM keys) Fixed wrong priority for XOR (should be less than NEG to get -1^1 to work) --- client/mysqldump.c | 25 +- include/mysql_embed.h | 2 + myisam/mi_check.c | 5 +- mysql-test/r/auto_increment.result | 52 ++--- mysql-test/r/bdb.result | 4 +- mysql-test/r/func_group.result | 15 +- mysql-test/r/func_str.result | 337 +++++++++++++++++++++++++++ mysql-test/r/func_time.result | 109 +++++++++ mysql-test/r/group_by.result | 11 +- mysql-test/r/innodb.result | 48 ++-- mysql-test/r/insert.result | 1 - mysql-test/r/join_outer.result | 9 +- mysql-test/r/loaddata.result | 10 +- mysql-test/r/multi_update.result | 2 +- mysql-test/r/mysqldump.result | 48 ++-- mysql-test/r/rpl_EE_error.result | 10 +- mysql-test/r/rpl_multi_update.result | 9 +- mysql-test/r/symlink.result | 8 +- mysql-test/r/type_blob.result | 2 +- mysql-test/r/type_datetime.result | 6 + mysql-test/r/type_decimal.result | 2 + mysql-test/r/type_enum.result | 4 + mysql-test/r/type_timestamp.result | 41 ++-- mysql-test/r/union.result | 3 +- mysql-test/r/warnings.result | 4 +- mysql-test/t/bdb.test | 4 +- mysql-test/t/innodb.test | 12 +- mysql-test/t/multi_update.test | 3 +- mysql-test/t/mysqldump.test | 8 +- mysql-test/t/rpl_EE_error.test | 4 +- mysql-test/t/rpl_multi_update.test | 5 +- mysql-test/t/union.test | 3 +- mysys/charset.c | 76 ++++-- mysys/my_handler.c | 8 + sql-common/client.c | 7 +- sql/field.cc | 7 +- sql/field.h | 11 +- sql/ha_innodb.cc | 2 - sql/item.cc | 4 +- sql/item.h | 1 + sql/item_func.cc | 31 +-- sql/item_func.h | 3 +- sql/item_strfunc.cc | 8 +- sql/item_subselect.cc | 16 +- sql/item_sum.cc | 12 +- sql/item_sum.h | 2 +- sql/mysql_priv.h | 6 - sql/mysqld.cc | 2 +- sql/set_var.cc | 6 +- sql/share/czech/errmsg.txt | 4 +- sql/share/danish/errmsg.txt | 4 +- sql/share/dutch/errmsg.txt | 4 +- sql/share/english/errmsg.txt | 4 +- sql/share/estonian/errmsg.txt | 4 +- sql/share/french/errmsg.txt | 4 +- sql/share/greek/errmsg.txt | 4 +- sql/share/hungarian/errmsg.txt | 4 +- sql/share/italian/errmsg.txt | 4 +- sql/share/japanese/errmsg.txt | 4 +- sql/share/korean/errmsg.txt | 4 +- sql/share/norwegian-ny/errmsg.txt | 4 +- sql/share/norwegian/errmsg.txt | 4 +- sql/share/polish/errmsg.txt | 4 +- sql/share/romanian/errmsg.txt | 4 +- sql/share/russian/errmsg.txt | 4 +- sql/share/serbian/errmsg.txt | 4 +- sql/share/slovak/errmsg.txt | 4 +- sql/share/spanish/errmsg.txt | 4 +- sql/share/swedish/errmsg.txt | 4 +- sql/share/ukrainian/errmsg.txt | 4 +- sql/sql_acl.h | 12 +- sql/sql_base.cc | 2 +- sql/sql_client.cc | 3 +- sql/sql_parse.cc | 275 ++++++++-------------- sql/sql_prepare.cc | 4 +- sql/sql_select.cc | 6 +- sql/sql_update.cc | 3 +- sql/sql_yacc.yy | 2 +- sql/table.cc | 3 +- 79 files changed, 908 insertions(+), 494 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index d5c80b31141..99bca9d96a4 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1427,25 +1427,16 @@ static void dumpTable(uint numFields, char *table) (*ptr == '-' && my_isalpha(charset_info, ptr[1]))) fputs("NULL", md_result_file); else if (field->type == FIELD_TYPE_DECIMAL) - { - /* add " signs around */ - fputs("\"", md_result_file); - fputs(ptr, md_result_file); - fputs("\"", md_result_file); - } - else - fputs(ptr, md_result_file); - } + { + /* add " signs around */ + fputs("\"", md_result_file); + fputs(ptr, md_result_file); + fputs("\"", md_result_file); + } + else + fputs(ptr, md_result_file); } } - else - { - if (opt_xml) - print_xml_tag1(md_result_file, "\t\t", "field name=", - field->name, "NULL\n"); - else - fputs("NULL", md_result_file); - } } } diff --git a/include/mysql_embed.h b/include/mysql_embed.h index 7a169d4133e..df358e29872 100644 --- a/include/mysql_embed.h +++ b/include/mysql_embed.h @@ -32,4 +32,6 @@ #undef MYSQL_SERVER_SUFFIX #define MYSQL_SERVER_SUFFIX "-embedded" +#undef HAVE_QUERY_CACHE /* Cache dosn't work yet */ + #endif /* EMBEDDED_LIBRARY */ diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 02bca2911b4..a55929805fa 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -512,6 +512,7 @@ int chk_key(MI_CHECK *param, register MI_INFO *info) DBUG_RETURN(result); } /* chk_key */ + static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t page, uchar *buff, ha_rows *keys, ha_checksum *key_checksum, uint level) @@ -553,7 +554,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, uint used_length,comp_flag,nod_flag,key_length,not_used; uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos; my_off_t next_page,record; - char llbuff[22],llbuff2[22]; + char llbuff[22]; DBUG_ENTER("chk_index"); DBUG_DUMP("buff",(byte*) buff,mi_getint(buff)); @@ -651,7 +652,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, if (record >= info->state->data_file_length) { #ifndef DBUG_OFF - char llbuff3[22]; + char llbuff2[22], llbuff3[22]; #endif mi_check_print_error(param,"Found key at page %s that points to record outside datafile",llstr(page,llbuff)); DBUG_PRINT("test",("page: %s record: %s filelength: %s", diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 1390141df51..89d07af6cf3 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -106,6 +106,32 @@ Table Op Msg_type Msg_text test.t1 check warning Found row where the auto_increment column has the value 0 test.t1 check status OK drop table t1; +create table t1 (a int not null auto_increment primary key); +insert into t1 values (NULL); +insert into t1 values (-1); +select last_insert_id(); +last_insert_id() +1 +insert into t1 values (NULL); +select * from t1; +a +-1 +1 +2 +drop table t1; +create table t1 (a int not null auto_increment primary key) /*!41002 type=heap */; +insert into t1 values (NULL); +insert into t1 values (-1); +select last_insert_id(); +last_insert_id() +1 +insert into t1 values (NULL); +select * from t1; +a +-1 +1 +2 +drop table t1; create table t1 (i tinyint unsigned not null auto_increment primary key); insert into t1 set i = 254; insert into t1 set i = null; @@ -244,29 +270,3 @@ a b 0 13 500 14 drop table t1; -create table t1 (a int not null auto_increment primary key); -insert into t1 values (NULL); -insert into t1 values (-1); -select last_insert_id(); -last_insert_id() -1 -insert into t1 values (NULL); -select * from t1; -a --1 -1 -2 -drop table t1; -create table t1 (a int not null auto_increment primary key) /*!41002 type=heap */; -insert into t1 values (NULL); -insert into t1 values (-1); -select last_insert_id(); -last_insert_id() -1 -insert into t1 values (NULL); -select * from t1; -a --1 -1 -2 -drop table t1; diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index dd5633af90d..b02574cf8a3 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -1145,14 +1145,14 @@ x 7 6 drop table t1; -create table t1 ( c char(8) not null ) type=bdb; +create table t1 ( c char(8) not null ) engine=bdb; insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); alter table t1 add b char(8) not null; alter table t1 add a char(8) not null; alter table t1 add primary key (a,b,c); update t1 set a=c, b=c; -create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=bdb; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) engine=bdb; insert into t2 select * from t1; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; drop table t1,t2; diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index ec00c850197..6a704f2847d 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -47,7 +47,7 @@ sum(all a) count(all a) avg(all a) std(all a) variance(all a) bit_or(all a) bit_ 21 6 3.5000 1.7078 2.9167 7 0 1 6 E select grp, sum(a),count(a),avg(a),std(a),variance(a),bit_or(a),bit_and(a),min(a),max(a),min(c),max(c) from t1 group by grp; grp sum(a) count(a) avg(a) std(a) variance(a) bit_or(a) bit_and(a) min(a) max(a) min(c) max(c) -NULL NULL 0 NULL NULL NULL 0 1844674407379551615 NULL NULL +NULL NULL 0 NULL NULL NULL 0 18446744073709551615 NULL NULL 1 1 1 1.0000 0.0000 0.0000 1 1 1 1 a a 2 5 2 2.5000 0.5000 0.2500 3 2 2 3 b c 3 15 3 5.0000 0.8165 0.6667 7 4 4 6 C E @@ -576,8 +576,8 @@ insert into t1 values (1,null); insert into t1 values (2,null); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL 0 0 -2 0 NULL NULL NULL NULL NULL 0 0 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 +2 0 NULL NULL NULL NULL NULL 18446744073709551615 0 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) 1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 @@ -585,8 +585,8 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) insert into t1 values (2,1); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL 0 0 -2 1 1 1.0000 0.0000 1 1 0 1 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 +2 1 1 1.0000 0.0000 1 1 1 1 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) 1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 @@ -594,8 +594,8 @@ a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) insert into t1 values (3,1); select a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) -1 0 NULL NULL NULL NULL NULL 0 0 -2 1 1 1.0000 0.0000 1 1 0 1 +1 0 NULL NULL NULL NULL NULL 18446744073709551615 0 +2 1 1 1.0000 0.0000 1 1 1 1 3 1 1 1.0000 0.0000 1 1 1 1 select SQL_BIG_RESULT a,count(b), sum(b), avg(b), std(b), min(b), max(b), bit_and(b), bit_or(b), bit_xor(b) from t1 group by a; a count(b) sum(b) avg(b) std(b) min(b) max(b) bit_and(b) bit_or(b) bit_xor(b) @@ -643,4 +643,3 @@ bit_and(col) bit_or(col) 18446744073709551614 18446744073709551614 18446744073709551615 18446744073709551615 drop table t1; - diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index aaebd33d010..c74feccfb7f 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -268,3 +268,340 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf'); SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password"); 1 DROP TABLE t1; +select 1=_latin1'1'; +1=_latin1'1' +1 +select _latin1'1'=1; +_latin1'1'=1 +1 +select _latin2'1'=1; +_latin2'1'=1 +1 +select 1=_latin2'1'; +1=_latin2'1' +1 +select _latin1'1'=_latin2'1'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation '=' +select row('a','b','c') = row('a','b','c'); +row('a','b','c') = row('a','b','c') +1 +select row('A','b','c') = row('a','b','c'); +row('A','b','c') = row('a','b','c') +1 +select row('A' COLLATE latin1_bin,'b','c') = row('a','b','c'); +row('A' COLLATE latin1_bin,'b','c') = row('a','b','c') +0 +select row('A','b','c') = row('a' COLLATE latin1_bin,'b','c'); +row('A','b','c') = row('a' COLLATE latin1_bin,'b','c') +0 +select row('A' COLLATE latin1_general_ci,'b','c') = row('a' COLLATE latin1_bin,'b','c'); +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation '=' +select concat(_latin1'a',_latin2'a'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat' +select concat(_latin1'a',_latin2'a',_latin5'a'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin5_turkish_ci,COERCIBLE) for operation 'concat' +select concat(_latin1'a',_latin2'a',_latin5'a',_latin7'a'); +ERROR HY000: Illegal mix of collations for operation 'concat' +select FIELD('b','A','B'); +FIELD('b','A','B') +2 +select FIELD('B','A','B'); +FIELD('B','A','B') +2 +select FIELD('b' COLLATE latin1_bin,'A','B'); +FIELD('b' COLLATE latin1_bin,'A','B') +0 +select FIELD('b','A' COLLATE latin1_bin,'B'); +FIELD('b','A' COLLATE latin1_bin,'B') +0 +select FIELD(_latin2'b','A','B'); +ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' +select FIELD('b',_latin2'A','B'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' +select FIELD('b',_latin2'A','B',1); +FIELD('b',_latin2'A','B',1) +1 +select POSITION(_latin1'B' IN _latin1'abcd'); +POSITION(_latin1'B' IN _latin1'abcd') +2 +select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin); +POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin) +0 +select POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd'); +POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd') +0 +select POSITION(_latin1'B' COLLATE latin1_general_ci IN _latin1'abcd' COLLATE latin1_bin); +ERROR HY000: Illegal mix of collations (latin1_bin,EXPLICIT) and (latin1_general_ci,EXPLICIT) for operation 'locate' +select POSITION(_latin1'B' IN _latin2'abcd'); +ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'locate' +select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d'); +FIND_IN_SET(_latin1'B',_latin1'a,b,c,d') +2 +select FIND_IN_SET(_latin1'B' COLLATE latin1_general_ci,_latin1'a,b,c,d' COLLATE latin1_bin); +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'find_in_set' +select FIND_IN_SET(_latin1'B',_latin2'a,b,c,d'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'find_in_set' +select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2); +SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2) +abcdabc +select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'substr_index' +select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2); +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation 'substr_index' +select _latin1'B' between _latin1'a' and _latin1'c'; +_latin1'B' between _latin1'a' and _latin1'c' +1 +select _latin1'B' collate latin1_bin between _latin1'a' and _latin1'c'; +_latin1'B' collate latin1_bin between _latin1'a' and _latin1'c' +0 +select _latin1'B' between _latin1'a' collate latin1_bin and _latin1'c'; +_latin1'B' between _latin1'a' collate latin1_bin and _latin1'c' +0 +select _latin1'B' between _latin1'a' and _latin1'c' collate latin1_bin; +_latin1'B' between _latin1'a' and _latin1'c' collate latin1_bin +0 +select _latin2'B' between _latin1'a' and _latin1'b'; +ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'between' +select _latin1'B' between _latin2'a' and _latin1'b'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'between' +select _latin1'B' between _latin1'a' and _latin2'b'; +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE) for operation 'between' +select _latin1'B' collate latin1_general_ci between _latin1'a' collate latin1_bin and _latin1'b'; +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_bin,EXPLICIT), (latin1_swedish_ci,COERCIBLE) for operation 'between' +select _latin1'B' in (_latin1'a',_latin1'b'); +_latin1'B' in (_latin1'a',_latin1'b') +1 +select _latin1'B' collate latin1_bin in (_latin1'a',_latin1'b'); +_latin1'B' collate latin1_bin in (_latin1'a',_latin1'b') +0 +select _latin1'B' in (_latin1'a' collate latin1_bin,_latin1'b'); +_latin1'B' in (_latin1'a' collate latin1_bin,_latin1'b') +0 +select _latin1'B' in (_latin1'a',_latin1'b' collate latin1_bin); +_latin1'B' in (_latin1'a',_latin1'b' collate latin1_bin) +0 +select _latin2'B' in (_latin1'a',_latin1'b'); +ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation ' IN ' +select _latin1'B' in (_latin2'a',_latin1'b'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation ' IN ' +select _latin1'B' in (_latin1'a',_latin2'b'); +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE) for operation ' IN ' +select _latin1'B' COLLATE latin1_general_ci in (_latin1'a' COLLATE latin1_bin,_latin1'b'); +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_bin,EXPLICIT), (latin1_swedish_ci,COERCIBLE) for operation ' IN ' +select _latin1'B' COLLATE latin1_general_ci in (_latin1'a',_latin1'b' COLLATE latin1_bin); +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT), (latin1_swedish_ci,COERCIBLE), (latin1_bin,EXPLICIT) for operation ' IN ' +select collation(bin(130)), coercibility(bin(130)); +collation(bin(130)) coercibility(bin(130)) +latin1_swedish_ci 3 +select collation(oct(130)), coercibility(oct(130)); +collation(oct(130)) coercibility(oct(130)) +latin1_swedish_ci 3 +select collation(conv(130,16,10)), coercibility(conv(130,16,10)); +collation(conv(130,16,10)) coercibility(conv(130,16,10)) +latin1_swedish_ci 3 +select collation(hex(130)), coercibility(hex(130)); +collation(hex(130)) coercibility(hex(130)) +latin1_swedish_ci 3 +select collation(char(130)), coercibility(hex(130)); +collation(char(130)) coercibility(hex(130)) +binary 3 +select collation(format(130,10)), coercibility(format(130,10)); +collation(format(130,10)) coercibility(format(130,10)) +latin1_swedish_ci 3 +select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a')); +collation(lcase(_latin2'a')) coercibility(lcase(_latin2'a')) +latin2_general_ci 3 +select collation(ucase(_latin2'a')), coercibility(ucase(_latin2'a')); +collation(ucase(_latin2'a')) coercibility(ucase(_latin2'a')) +latin2_general_ci 3 +select collation(left(_latin2'a',1)), coercibility(left(_latin2'a',1)); +collation(left(_latin2'a',1)) coercibility(left(_latin2'a',1)) +latin2_general_ci 3 +select collation(right(_latin2'a',1)), coercibility(right(_latin2'a',1)); +collation(right(_latin2'a',1)) coercibility(right(_latin2'a',1)) +latin2_general_ci 3 +select collation(substring(_latin2'a',1,1)), coercibility(substring(_latin2'a',1,1)); +collation(substring(_latin2'a',1,1)) coercibility(substring(_latin2'a',1,1)) +latin2_general_ci 3 +select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b')); +collation(concat(_latin2'a',_latin2'b')) coercibility(concat(_latin2'a',_latin2'b')) +latin2_general_ci 3 +select collation(lpad(_latin2'a',4,_latin2'b')), coercibility(lpad(_latin2'a',4,_latin2'b')); +collation(lpad(_latin2'a',4,_latin2'b')) coercibility(lpad(_latin2'a',4,_latin2'b')) +latin2_general_ci 3 +select collation(rpad(_latin2'a',4,_latin2'b')), coercibility(rpad(_latin2'a',4,_latin2'b')); +collation(rpad(_latin2'a',4,_latin2'b')) coercibility(rpad(_latin2'a',4,_latin2'b')) +latin2_general_ci 3 +select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b')); +collation(concat_ws(_latin2'a',_latin2'b')) coercibility(concat_ws(_latin2'a',_latin2'b')) +latin2_general_ci 3 +select collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')), coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c')); +collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')) coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c')) +latin2_general_ci 3 +select collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')), coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' ')); +collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')) coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' ')) +binary 3 +select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a ')); +collation(trim(_latin2' a ')) coercibility(trim(_latin2' a ')) +latin2_general_ci 3 +select collation(ltrim(_latin2' a ')), coercibility(ltrim(_latin2' a ')); +collation(ltrim(_latin2' a ')) coercibility(ltrim(_latin2' a ')) +latin2_general_ci 3 +select collation(rtrim(_latin2' a ')), coercibility(rtrim(_latin2' a ')); +collation(rtrim(_latin2' a ')) coercibility(rtrim(_latin2' a ')) +latin2_general_ci 3 +select collation(trim(LEADING _latin2' ' FROM _latin2'a')), coercibility(trim(LEADING _latin2'a' FROM _latin2'a')); +collation(trim(LEADING _latin2' ' FROM _latin2'a')) coercibility(trim(LEADING _latin2'a' FROM _latin2'a')) +latin2_general_ci 3 +select collation(trim(TRAILING _latin2' ' FROM _latin2'a')), coercibility(trim(TRAILING _latin2'a' FROM _latin2'a')); +collation(trim(TRAILING _latin2' ' FROM _latin2'a')) coercibility(trim(TRAILING _latin2'a' FROM _latin2'a')) +latin2_general_ci 3 +select collation(trim(BOTH _latin2' ' FROM _latin2'a')), coercibility(trim(BOTH _latin2'a' FROM _latin2'a')); +collation(trim(BOTH _latin2' ' FROM _latin2'a')) coercibility(trim(BOTH _latin2'a' FROM _latin2'a')) +latin2_general_ci 3 +select collation(repeat(_latin2'a',10)), coercibility(repeat(_latin2'a',10)); +collation(repeat(_latin2'a',10)) coercibility(repeat(_latin2'a',10)) +latin2_general_ci 3 +select collation(reverse(_latin2'ab')), coercibility(reverse(_latin2'ab')); +collation(reverse(_latin2'ab')) coercibility(reverse(_latin2'ab')) +latin2_general_ci 3 +select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab')); +collation(quote(_latin2'ab')) coercibility(quote(_latin2'ab')) +latin2_general_ci 3 +select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab')); +collation(soundex(_latin2'ab')) coercibility(soundex(_latin2'ab')) +latin2_general_ci 3 +select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1)); +collation(substring(_latin2'ab',1)) coercibility(substring(_latin2'ab',1)) +latin2_general_ci 3 +select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef')); +collation(insert(_latin2'abcd',2,3,_latin2'ef')) coercibility(insert(_latin2'abcd',2,3,_latin2'ef')) +latin2_general_ci 3 +select collation(replace(_latin2'abcd',_latin2'b',_latin2'B')), coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B')); +collation(replace(_latin2'abcd',_latin2'b',_latin2'B')) coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B')) +latin2_general_ci 3 +create table t1 +select +bin(130), +oct(130), +conv(130,16,10), +hex(130), +char(130), +format(130,10), +left(_latin2'a',1), +right(_latin2'a',1), +lcase(_latin2'a'), +ucase(_latin2'a'), +substring(_latin2'a',1,1), +concat(_latin2'a',_latin2'b'), +lpad(_latin2'a',4,_latin2'b'), +rpad(_latin2'a',4,_latin2'b'), +concat_ws(_latin2'a',_latin2'b'), +make_set(255,_latin2'a',_latin2'b',_latin2'c'), +export_set(255,_latin2'y',_latin2'n',_latin2' '), +trim(_latin2' a '), +ltrim(_latin2' a '), +rtrim(_latin2' a '), +trim(LEADING _latin2' ' FROM _latin2' a '), +trim(TRAILING _latin2' ' FROM _latin2' a '), +trim(BOTH _latin2' ' FROM _latin2' a '), +repeat(_latin2'a',10), +reverse(_latin2'ab'), +quote(_latin2'ab'), +soundex(_latin2'ab'), +substring(_latin2'ab',1), +insert(_latin2'abcd',2,3,_latin2'ef'), +replace(_latin2'abcd',_latin2'b',_latin2'B') +; +Warnings: +Warning 1264 Data truncated for column 'format(130,10)' at row 1 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `bin(130)` char(64) NOT NULL default '', + `oct(130)` char(64) NOT NULL default '', + `conv(130,16,10)` char(64) NOT NULL default '', + `hex(130)` char(6) NOT NULL default '', + `char(130)` char(1) NOT NULL default '', + `format(130,10)` char(4) NOT NULL default '', + `left(_latin2'a',1)` char(1) character set latin2 NOT NULL default '', + `right(_latin2'a',1)` char(1) character set latin2 NOT NULL default '', + `lcase(_latin2'a')` char(1) character set latin2 NOT NULL default '', + `ucase(_latin2'a')` char(1) character set latin2 NOT NULL default '', + `substring(_latin2'a',1,1)` char(1) character set latin2 NOT NULL default '', + `concat(_latin2'a',_latin2'b')` char(2) character set latin2 NOT NULL default '', + `lpad(_latin2'a',4,_latin2'b')` char(4) character set latin2 NOT NULL default '', + `rpad(_latin2'a',4,_latin2'b')` char(4) character set latin2 NOT NULL default '', + `concat_ws(_latin2'a',_latin2'b')` char(1) character set latin2 NOT NULL default '', + `make_set(255,_latin2'a',_latin2'b',_latin2'c')` char(5) character set latin2 NOT NULL default '', + `export_set(255,_latin2'y',_latin2'n',_latin2' ')` char(127) character set latin2 NOT NULL default '', + `trim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', + `ltrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', + `rtrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', + `trim(LEADING _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '', + `trim(TRAILING _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '', + `trim(BOTH _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '', + `repeat(_latin2'a',10)` char(10) character set latin2 NOT NULL default '', + `reverse(_latin2'ab')` char(2) character set latin2 NOT NULL default '', + `quote(_latin2'ab')` char(6) character set latin2 NOT NULL default '', + `soundex(_latin2'ab')` char(4) character set latin2 NOT NULL default '', + `substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '', + `insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default '', + `replace(_latin2'abcd',_latin2'b',_latin2'B')` char(4) character set latin2 NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +select SUBSTR('abcdefg',3,2); +SUBSTR('abcdefg',3,2) +cd +select SUBSTRING('abcdefg',3,2); +SUBSTRING('abcdefg',3,2) +cd +select SUBSTR('abcdefg',-3,2) FROM DUAL; +SUBSTR('abcdefg',-3,2) +ef +select SUBSTR('abcdefg',-1,5) FROM DUAL; +SUBSTR('abcdefg',-1,5) +g +select SUBSTR('abcdefg',0,0) FROM DUAL; +SUBSTR('abcdefg',0,0) + +select SUBSTR('abcdefg',-1,-1) FROM DUAL; +SUBSTR('abcdefg',-1,-1) + +select SUBSTR('abcdefg',1,-1) FROM DUAL; +SUBSTR('abcdefg',1,-1) + +create table t7 (s1 char); +select * from t7 +where concat(s1 collate latin1_general_ci,s1 collate latin1_swedish_ci) = 'AA'; +ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_swedish_ci,EXPLICIT) for operation 'concat' +drop table t7; +CREATE TABLE t1 ( +wid int(10) unsigned NOT NULL auto_increment, +data_podp date default NULL, +status_wnio enum('nowy','podp','real','arch') NOT NULL default 'nowy', +PRIMARY KEY(wid), +); +INSERT INTO t1 VALUES (8,NULL,'real'); +INSERT INTO t1 VALUES (9,NULL,'nowy'); +SELECT elt(status_wnio,data_podp) FROM t1 GROUP BY wid; +elt(status_wnio,data_podp) +NULL +NULL +DROP TABLE t1; +CREATE TABLE t1 (title text) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('Congress reconvenes in September to debate welfare and adult education'); +INSERT INTO t1 VALUES ('House passes the CAREERS bill'); +SELECT CONCAT("",RPAD("",(55 - LENGTH(title)),".")) from t1; +CONCAT("",RPAD("",(55 - LENGTH(title)),".")) +NULL +.......................... +DROP TABLE t1; +select substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2),substring_index("1abcd;2abcd;3abcd;4abcd", ';', -2); +substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2) substring_index("1abcd;2abcd;3abcd;4abcd", ';', -2) +1abcd;2abcd 3abcd;4abcd +explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'mood' sounds like 'mud', aes_decrypt(aes_encrypt('abc','1'),'1'),concat('*',space(5),'*'), reverse('abc'), rpad('a',4,'1'), lpad('a',4,'1'), concat_ws(',','',NULL,'a'),make_set(255,_latin2'a',_latin2'b',_latin2'c'),elt(2,1),locate("a","b",2),format(130,10),char(0),conv(130,16,10),hex(130),binary 'HE', export_set(255,_latin2'y',_latin2'n',_latin2' '),FIELD('b' COLLATE latin1_bin,'A','B'),FIND_IN_SET(_latin1'B',_latin1'a,b,c,d'),collation(conv(130,16,10)), coercibility(conv(130,16,10)),length('\n\t\r\b\0\_\%\\'),bit_length('\n\t\r\b\0\_\%\\'),bit_length('\n\t\r\b\0\_\%\\'),concat('monty',' was here ','again'),length('hello'),char(ascii('h')),ord('h'),quote(1/0),crc32("123"),replace('aaaa','a','b'),insert('txs',2,1,'hi'),left(_latin2'a',1),right(_latin2'a',1),lcase(_latin2'a'),ucase(_latin2'a'),SUBSTR('abcdefg',3,2),substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2),trim(_latin2' a '),ltrim(_latin2' a '),rtrim(_latin2' a '), decode(encode(repeat("a",100000),"monty"),"monty"); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select high_priority md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,(_latin1'HE' collate _latin1'BINARY') AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate _latin1'latin1_bin'),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substr_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")` diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index c3f4b9475f9..0998f7b8bcf 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -431,3 +431,112 @@ select * from t1, t3 where t1.start between t3.ctime1 and t3.ctime2; start ctime1 ctime2 2002-11-04 00:00:00 2002-10-29 16:51:06 2002-11-05 16:47:31 drop table t1,t2,t3; +select @a:=FROM_UNIXTIME(1); +@a:=FROM_UNIXTIME(1) +1970-01-01 03:00:01 +select unix_timestamp(@a); +unix_timestamp(@a) +1 +select unix_timestamp('1969-12-01 19:00:01'); +unix_timestamp('1969-12-01 19:00:01') +0 +CREATE TABLE t1 (datetime datetime, timestamp timestamp, date date, time time); +INSERT INTO t1 values ("2001-01-02 03:04:05", "2002-01-02 03:04:05", "2003-01-02", "06:07:08"); +SELECT * from t1; +datetime timestamp date time +2001-01-02 03:04:05 2002-01-02 03:04:05 2003-01-02 06:07:08 +select date_add("1997-12-31",INTERVAL 1 SECOND); +date_add("1997-12-31",INTERVAL 1 SECOND) +1997-12-31 00:00:01 +select date_add("1997-12-31",INTERVAL "1 1" YEAR_MONTH); +date_add("1997-12-31",INTERVAL "1 1" YEAR_MONTH) +1999-01-31 +select date_add(datetime, INTERVAL 1 SECOND) from t1; +date_add(datetime, INTERVAL 1 SECOND) +2001-01-02 03:04:06 +select date_add(datetime, INTERVAL 1 YEAR) from t1; +date_add(datetime, INTERVAL 1 YEAR) +2002-01-02 03:04:05 +select date_add(date,INTERVAL 1 SECOND) from t1; +date_add(date,INTERVAL 1 SECOND) +2003-01-02 00:00:01 +select date_add(date,INTERVAL 1 MINUTE) from t1; +date_add(date,INTERVAL 1 MINUTE) +2003-01-02 00:01:00 +select date_add(date,INTERVAL 1 HOUR) from t1; +date_add(date,INTERVAL 1 HOUR) +2003-01-02 01:00:00 +select date_add(date,INTERVAL 1 DAY) from t1; +date_add(date,INTERVAL 1 DAY) +2003-01-03 +select date_add(date,INTERVAL 1 MONTH) from t1; +date_add(date,INTERVAL 1 MONTH) +2003-02-02 +select date_add(date,INTERVAL 1 YEAR) from t1; +date_add(date,INTERVAL 1 YEAR) +2004-01-02 +select date_add(date,INTERVAL "1:1" MINUTE_SECOND) from t1; +date_add(date,INTERVAL "1:1" MINUTE_SECOND) +2003-01-02 00:01:01 +select date_add(date,INTERVAL "1:1" HOUR_MINUTE) from t1; +date_add(date,INTERVAL "1:1" HOUR_MINUTE) +2003-01-02 01:01:00 +select date_add(date,INTERVAL "1:1" DAY_HOUR) from t1; +date_add(date,INTERVAL "1:1" DAY_HOUR) +2003-01-03 01:00:00 +select date_add(date,INTERVAL "1 1" YEAR_MONTH) from t1; +date_add(date,INTERVAL "1 1" YEAR_MONTH) +2004-02-02 +select date_add(date,INTERVAL "1:1:1" HOUR_SECOND) from t1; +date_add(date,INTERVAL "1:1:1" HOUR_SECOND) +2003-01-02 01:01:01 +select date_add(date,INTERVAL "1 1:1" DAY_MINUTE) from t1; +date_add(date,INTERVAL "1 1:1" DAY_MINUTE) +2003-01-03 01:01:00 +select date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) from t1; +date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) +2003-01-03 01:01:01 +select date_add(time,INTERVAL 1 SECOND) from t1; +date_add(time,INTERVAL 1 SECOND) +2006-07-08 00:00:01 +drop table t1; +select last_day('2000-02-05') as f1, last_day('2002-12-31') as f2, +last_day('2003-03-32') as f3, last_day('2003-04-01') as f4, +last_day('2001-01-01 01:01:01') as f5, last_day(NULL), +last_day('2001-02-12'); +f1 f2 f3 f4 f5 last_day(NULL) last_day('2001-02-12') +2000-02-29 2002-12-31 NULL 2003-04-30 2001-01-31 NULL 2001-02-28 +create table t1 select last_day('2000-02-05') as a; +describe t1; +Field Type Null Key Default Extra +a date 0000-00-00 +select * from t1; +a +2000-02-29 +drop table t1; +select last_day('2000-02-05'); +last_day('2000-02-05') +2000-02-29 +select strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0; +strcmp(date_sub(localtimestamp(), interval 3 hour), utc_timestamp())=0 +1 +select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0; +strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%T"), utc_time())=0 +1 +select strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0; +strcmp(date_format(date_sub(localtimestamp(), interval 3 hour),"%Y-%m-%d"), utc_date())=0 +1 +select strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0; +strcmp(date_format(utc_timestamp(),"%T"), utc_time())=0 +1 +select strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0; +strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0 +1 +select strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0; +strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0 +1 +explain extended select period_add("9602",-12),period_diff(199505,"9404"),from_days(to_days("960101")),dayofmonth("1997-01-02"), month("1997-01-02"), monthname("1972-03-04"),dayofyear("0000-00-00"),HOUR("1997-03-03 23:03:22"),MINUTE("23:03:22"),SECOND(230322),QUARTER(980303),WEEK("1998-03-03"),yearweek("2000-01-01",1),week(19950101,1),year("98-02-03"),weekday(curdate())-weekday(now()),dayname("1962-03-03"),unix_timestamp(),sec_to_time(time_to_sec("0:30:47")/6.21),curtime(),utc_time(),curdate(),utc_date(),utc_timestamp(),date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w"),from_unixtime(unix_timestamp("1994-03-02 10:11:12")),"1997-12-31 23:59:59" + INTERVAL 1 SECOND,"1998-01-01 00:00:00" - INTERVAL 1 SECOND,INTERVAL 1 DAY + "1997-12-31", extract(YEAR FROM "1999-01-02 10:11:12"),date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select high_priority no_cache period_add(_latin1'9602',-(12)) AS `period_add("9602",-12)`,period_diff(199505,_latin1'9404') AS `period_diff(199505,"9404")`,from_days(to_days(_latin1'960101')) AS `from_days(to_days("960101"))`,dayofmonth(_latin1'1997-01-02') AS `dayofmonth("1997-01-02")`,month(_latin1'1997-01-02') AS `month("1997-01-02")`,monthname(_latin1'1972-03-04') AS `monthname("1972-03-04")`,dayofyear(_latin1'0000-00-00') AS `dayofyear("0000-00-00")`,hour(_latin1'1997-03-03 23:03:22') AS `HOUR("1997-03-03 23:03:22")`,minute(_latin1'23:03:22') AS `MINUTE("23:03:22")`,second(230322) AS `SECOND(230322)`,quarter(980303) AS `QUARTER(980303)`,week(_latin1'1998-03-03',0) AS `WEEK("1998-03-03")`,yearweek(_latin1'2000-01-01',1) AS `yearweek("2000-01-01",1)`,week(19950101,1) AS `week(19950101,1)`,year(_latin1'98-02-03') AS `year("98-02-03")`,(weekday(to_days(curdate())) - weekday(to_days(now()))) AS `weekday(curdate())-weekday(now())`,dayname(to_days(_latin1'1962-03-03')) AS `dayname("1962-03-03")`,unix_timestamp() AS `unix_timestamp()`,sec_to_time((time_to_sec(_latin1'0:30:47') / 6.21)) AS `sec_to_time(time_to_sec("0:30:47")/6.21)`,curtime() AS `curtime()`,utc_time() AS `utc_time()`,curdate() AS `curdate()`,utc_date() AS `utc_date()`,utc_timestamp() AS `utc_timestamp()`,date_format(_latin1'1997-01-02 03:04:05',_latin1'%M %W %D %Y %y %m %d %h %i %s %w') AS `date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")`,from_unixtime(unix_timestamp(_latin1'1994-03-02 10:11:12')) AS `from_unixtime(unix_timestamp("1994-03-02 10:11:12"))`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `"1997-12-31 23:59:59" + INTERVAL 1 SECOND`,(_latin1'1998-01-01 00:00:00' - interval 1 second) AS `"1998-01-01 00:00:00" - INTERVAL 1 SECOND`,(_latin1'1997-12-31' + interval 1 day) AS `INTERVAL 1 DAY + "1997-12-31"`,extract(year from _latin1'1999-01-02 10:11:12') AS `extract(YEAR FROM "1999-01-02 10:11:12")`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)` diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 98a4f9a390d..bbe3326fd34 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -284,13 +284,14 @@ select spid,count(*) from t1 where spid between 1 and 2 group by spid desc; spid count(*) 2 2 1 1 +explain extended select sql_big_result spid,sum(userid) from t1 group by spid desc; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using filesort Warnings: Note 1003 select high_priority big_result test.t1.spID AS `spid`,sum(test.t1.userID) AS `sum(userid)` from test.t1 group by test.t1.spID desc explain select sql_big_result spid,sum(userid) from t1 group by spid desc order by null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 8 +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using filesort select sql_big_result spid,sum(userid) from t1 group by spid desc; spid sum(userid) 7 3 @@ -611,8 +612,8 @@ userid count(*) 2 1 1 2 EXPLAIN SELECT userid,count(*) FROM t1 GROUP BY userid DESC; -table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort DROP TABLE t1; CREATE TABLE t1 ( i int(11) default NULL, @@ -625,6 +626,6 @@ i COUNT(DISTINCT(i)) 2 1 4 4 explain SELECT i, COUNT(DISTINCT(i)) FROM t1 GROUP BY j ORDER BY NULL; -table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 6 Using filesort +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using filesort DROP TABLE t1; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index d7bcea22dbf..eb0b9af8e38 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1312,17 +1312,41 @@ a b 111 100 111 100 drop table t1; +create table t1 ( c char(8) not null ) engine=innodb; +insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); +insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); +alter table t1 add b char(8) not null; +alter table t1 add a char(8) not null; +alter table t1 add primary key (a,b,c); +update t1 set a=c, b=c; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) engine=innodb; +insert into t2 select * from t1; +delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; +drop table t1,t2; +SET AUTOCOMMIT=1; +create table t1 (a integer auto_increment primary key) engine=innodb; +insert into t1 (a) values (NULL),(NULL); +truncate table t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +a +3 +4 +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; insert into t1 values (1),(2),(3); -insert into t2 values (1, 20020204130000),(2, 20020204130000),(4,20020204310000 ); +insert into t2 values (1, 20020204130000),(2, 20020204130000),(4,20020204310000 ),(5,20020204230000); +Warnings: +Warning 1264 Data truncated for column 'stamp' at row 3 SELECT col1 FROM t1 UNION SELECT col1 FROM t2 WHERE stamp < '20020204120000' GROUP BY col1; col1 1 2 3 +4 drop table t1,t2; CREATE TABLE t1 ( `id` int(10) unsigned NOT NULL auto_increment, @@ -1352,7 +1376,6 @@ id label 1822 Test 3 3524 Societe Test 3525 Fournisseur Test -drop table t1; drop table t1,t2; create table t1 (c1 char(5) unique not null, c2 int, stamp timestamp) engine=innodb; select * from t1; @@ -1391,24 +1414,3 @@ test.t2 968604391 test.t3 968604391 test.t4 NULL drop table t1,t2,t3; -create table t1 ( c char(8) not null ) type=innodb; -insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); -insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); -alter table t1 add b char(8) not null; -alter table t1 add a char(8) not null; -alter table t1 add primary key (a,b,c); -update t1 set a=c, b=c; -create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=innodb; -insert into t2 select * from t1; -delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; -drop table t1,t2; -SET AUTOCOMMIT=1; -create table t1 (a integer auto_increment primary key) type=innodb; -insert into t1 (a) values (NULL),(NULL); -truncate table t1; -insert into t1 (a) values (NULL),(NULL); -SELECT * from t1; -a -3 -4 -drop table t1; diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 5af46e7db04..ff5111c552e 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -61,7 +61,6 @@ drop table t1; create table t1 (id int NOT NULL DEFAULT 8); insert into t1 values(NULL); ERROR 23000: Column 'id' cannot be null -ERROR 23000: Column 'id' cannot be null insert into t1 values (1), (NULL), (2); Warnings: Warning 1262 Data truncated, NULL supplied to NOT NULL column 'id' at row 2 diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 19368ace977..c40f86827f8 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -4,7 +4,6 @@ grp int(11) default NULL, a bigint(20) unsigned default NULL, c char(10) NOT NULL default '' ) ENGINE=MyISAM; -) ENGINE=MyISAM; INSERT INTO t1 VALUES (1,1,'a'),(2,2,'b'),(2,3,'c'),(3,4,'E'),(3,5,'C'),(3,6,'D'),(NULL,NULL,''); create table t2 (id int, a bigint unsigned not null, c char(10), d int, primary key (a)); insert into t2 values (1,1,"a",1),(3,4,"A",4),(3,5,"B",5),(3,6,"C",6),(4,7,"D",7); @@ -678,8 +677,8 @@ a1 a2 b1 b2 c1 c2 2 2 2 3 NULL NULL 3 2 NULL NULL 3 4 explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null; -table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 3 -t2 ALL NULL NULL NULL NULL 2 -t3 ALL NULL NULL NULL NULL 2 +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 drop table t1, t2, t3; diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index d90ebb4cd79..0547596dfbd 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -31,7 +31,7 @@ drop table t1; create table t1 (a text, b text); load data infile '../../std_data/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; Warnings: -Warning 1260 Record count is fewer than the column count at row 3 +Warning 1260 Row 3 doesn't contain data for all columns select concat('|',a,'|'), concat('|',b,'|') from t1; concat('|',a,'|') concat('|',b,'|') |Field A| |Field B| @@ -42,6 +42,11 @@ Field 3,'Field 4| drop table t1; create table t1 (a int, b char(10)); load data infile '../../std_data/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines; +Warnings: +Warning 1264 Data truncated for column 'a' at row 3 +Warning 1261 Row 3 was truncated; It contained more data than there where input columns +Warning 1264 Data truncated for column 'a' at row 5 +Warning 1261 Row 5 was truncated; It contained more data than there where input columns select * from t1; a b 1 row 1 @@ -51,6 +56,9 @@ a b 0 1234567890 truncate table t1; load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines; +Warnings: +Warning 1264 Data truncated for column 'a' at row 4 +Warning 1260 Row 4 doesn't contain data for all columns select * from t1; a b 1 row 1 diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 2e561452b8b..d335c9c1d10 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -351,7 +351,6 @@ a b 3 4 4 5 drop table t1; -drop table if exists t1, t2; create table t1(id1 smallint(5), field char(5)); create table t2(id2 smallint(5), field char(5)); insert into t1 values (1, 'a'), (2, 'aa'); @@ -396,3 +395,4 @@ t2 rows after big delete 1900001 select 't1 rows after big delete', count(*) from t1; t1 rows after big delete count(*) t1 rows after big delete 1900001 +drop table t1,t2; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 706a4d11241..04effdfef7c 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -21,21 +21,42 @@ DROP TABLE t1; CREATE TABLE t1 (a decimal(240, 20)); INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), ("0987654321098765432109876543210987654321"); +DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( a decimal(240,20) default NULL -) TYPE=MyISAM; +) ENGINE=MyISAM DEFAULT CHARSET=latin1; -INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890.00000000000000000000"); -INSERT INTO t1 VALUES ("0987654321098765432109876543210987654321.00000000000000000000"); + +/*!40000 ALTER TABLE t1 DISABLE KEYS */; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890.00000000000000000000"),("0987654321098765432109876543210987654321.00000000000000000000"); +UNLOCK TABLES; +/*!40000 ALTER TABLE t1 ENABLE KEYS */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; DROP TABLE t1; CREATE TABLE t1 (a double); INSERT INTO t1 VALUES (-9e999999); +DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( a double default NULL -) TYPE=MyISAM; +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +/*!40000 ALTER TABLE t1 DISABLE KEYS */; +LOCK TABLES t1 WRITE; INSERT INTO t1 VALUES (RES); +UNLOCK TABLES; +/*!40000 ALTER TABLE t1 ENABLE KEYS */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; DROP TABLE t1; CREATE TABLE t1(a int, b text, c varchar(3)); @@ -84,30 +105,11 @@ INSERT INTO t1 VALUES ("1\""), ("\"2"); DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'); --- MySQL dump 10.3 --- --- Host: localhost Database: test --- ------------------------------------------------------ --- Server version 4.1.2-alpha-debug-log - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT, CHARACTER_SET_CLIENT=utf8 */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */; - --- --- Table structure for table `t1` --- - DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( a varchar(255) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=koi8r; --- --- Dumping data for table `t1` --- - /*!40000 ALTER TABLE t1 DISABLE KEYS */; LOCK TABLES t1 WRITE; diff --git a/mysql-test/r/rpl_EE_error.result b/mysql-test/r/rpl_EE_error.result index a5043250df6..49ad4832c81 100644 --- a/mysql-test/r/rpl_EE_error.result +++ b/mysql-test/r/rpl_EE_error.result @@ -1,16 +1,16 @@ -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; -create table t1 (a int) type=myisam; +start slave; +create table t1 (a int) engine=myisam; flush tables; drop table t1; -create table t1 (a int, unique(a)) type=myisam; +create table t1 (a int, unique(a)) engine=myisam; set sql_log_bin=0; insert into t1 values(2); set sql_log_bin=1; insert into t1 values(1),(2); -Duplicate entry '2' for key 1 +ERROR 23000: Duplicate entry '2' for key 1 drop table t1; diff --git a/mysql-test/r/rpl_multi_update.result b/mysql-test/r/rpl_multi_update.result index 1fa1dd104d2..65587d25f63 100644 --- a/mysql-test/r/rpl_multi_update.result +++ b/mysql-test/r/rpl_multi_update.result @@ -1,18 +1,17 @@ -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; -drop table if exists t1,t2; +start slave; CREATE TABLE t1 ( a int unsigned not null auto_increment primary key, b int unsigned, -) TYPE=MyISAM; +) ENGINE=MyISAM; CREATE TABLE t2 ( a int unsigned not null auto_increment primary key, b int unsigned -) TYPE=MyISAM; +) ENGINE=MyISAM; INSERT INTO t1 VALUES (NULL, 0); INSERT INTO t1 SELECT NULL, 0 FROM t1; INSERT INTO t2 VALUES (NULL, 0), (NULL,1); diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 5f726476d96..4ba0ca0eac4 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -65,22 +65,24 @@ t9 CREATE TABLE `t9` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='TEST_DIR/var/tmp/' INDEX DIRECTORY='TEST_DIR/var/run/' drop database mysqltest; create table t1 (a int not null) type=myisam; +Warnings: +Warning 1286 'TYPE=database_engine' is deprecated. Use 'ENGINE=database_engine' instead. show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL default '0' -) TYPE=MyISAM +) ENGINE=MyISAM DEFAULT CHARSET=latin1 alter table t1 add b int; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL default '0', `b` int(11) default NULL -) TYPE=MyISAM +) ENGINE=MyISAM DEFAULT CHARSET=latin1 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL default '0', `b` int(11) default NULL -) TYPE=MyISAM +) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index f069114f752..255b7f0d942 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -585,9 +585,9 @@ create table t1 (id integer primary key auto_increment, txt text, unique index t insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); select * from t1 where txt='Chevy' or txt is NULL; id txt -3 NULL 1 Chevy 2 Chevy +3 NULL select * from t1 where txt='Chevy '; id txt 1 Chevy diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index a32c97f1d49..c1ee621697d 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -1,6 +1,12 @@ drop table if exists t1; create table t1 (t datetime); insert into t1 values(101),(691231),(700101),(991231),(10000101),(99991231),(101000000),(691231000000),(700101000000),(991231235959),(10000101000000),(99991231235959),(20030102030460),(20030102036301),(20030102240401),(20030132030401),(20031302030460); +Warnings: +Warning 1264 Data truncated for column 't' at row 13 +Warning 1264 Data truncated for column 't' at row 14 +Warning 1264 Data truncated for column 't' at row 15 +Warning 1264 Data truncated for column 't' at row 16 +Warning 1264 Data truncated for column 't' at row 17 select * from t1; t 2000-01-01 00:00:00 diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index ee7d6583d64..3d3e5082b8a 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -446,6 +446,8 @@ CREATE TABLE t1 (a_dec DECIMAL(-1,1)); ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '-1,1))' at line 1 create table t1(a decimal(10,4)); insert into t1 values ("+0000100000000"); +Warnings: +Warning 1263 Data truncated, out of range for column 'a' at row 1 select * from t1; a 9999999.9999 diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index e13a93a4156..8a7c15f7da9 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -1638,10 +1638,14 @@ t1 CREATE TABLE `t1` ( drop table t1; create table t1 (a enum ('0','1')); insert into t1 set a='foobar'; +Warnings: +Warning 1264 Data truncated for column 'a' at row 1 select * from t1; a update t1 set a = replace(a,'x','y'); +Warnings: +Warning 1264 Data truncated for column 'a' at row 1 select * from t1; a diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index a5d3abcdefc..172ccc440f4 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -24,15 +24,6 @@ a t 7 2002-03-05 00:00:00 8 0000-00-00 00:00:00 9 1970-01-01 03:20:38 -1 1970-01-01 03:20:34 -2 2002-03-03 00:00:00 -3 1970-01-01 03:20:35 -4 1970-01-01 03:20:36 -5 2002-03-04 00:00:00 -6 1970-01-01 03:20:37 -7 2002-03-05 00:00:00 -8 0000-00-00 00:00:00 -9 1970-01-01 03:20:38 drop table t1,t2; SET TIMESTAMP=1234; CREATE TABLE t1 (value TEXT NOT NULL, id VARCHAR(32) NOT NULL, stamp timestamp, PRIMARY KEY (id)); @@ -53,6 +44,12 @@ date_format(a,"%Y %y") year(a) year(now()) drop table t1; create table t1 (ix timestamp); insert into t1 values (19991101000000),(19990102030405),(19990630232922),(19990601000000),(19990930232922),(19990531232922),(19990501000000),(19991101000000),(19990501000000),(20030101010160),(20030101016001),(20030101240101),(20030132010101),(20031301010101); +Warnings: +Warning 1264 Data truncated for column 'ix' at row 10 +Warning 1264 Data truncated for column 'ix' at row 11 +Warning 1264 Data truncated for column 'ix' at row 12 +Warning 1264 Data truncated for column 'ix' at row 13 +Warning 1264 Data truncated for column 'ix' at row 14 select ix+0 from t1; ix+0 19991101000000 @@ -64,24 +61,24 @@ ix+0 19990501000000 19991101000000 19990501000000 -00000000000000 -00000000000000 -00000000000000 -00000000000000 -00000000000000 +0 +0 +0 +0 +0 delete from t1; insert into t1 values ("19991101000000"),("19990102030405"),("19990630232922"),("19990601000000"),("20030101010160"),("20030101016001"),("20030101240101"),("20030132010101"),("20031301010101"); -select * from t1; -ix +select ix+0 from t1; +ix+0 19991101000000 19990102030405 19990630232922 19990601000000 -00000000000000 -00000000000000 -00000000000000 -00000000000000 -00000000000000 +0 +0 +0 +0 +0 drop table t1; CREATE TABLE t1 (date date, date_time datetime, time_stamp timestamp); INSERT INTO t1 VALUES ("1998-12-31","1998-12-31 23:59:59",19981231235959); @@ -132,4 +129,4 @@ t2 t4 t6 t8 t10 t12 t14 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 1997-12-31 23:47:59 drop table t1; create table t1 (a timestamp default 1); -Invalid default value for 'a' +ERROR 42000: Invalid default value for 'a' diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 1cfc6eedbaf..4a514e3dd18 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -435,8 +435,9 @@ a (SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1; ERROR 42000: Wrong usage/placement of 'SQL_CALC_FOUND_ROWS' create temporary table t1 select a from t1 union select a from t2; +drop temporary table t1; create table t1 select a from t1 union select a from t2; -INSERT TABLE 't1' isn't allowed in FROM table list +ERROR HY000: You can't specify target table 't1' for update in FROM clause drop table t1,t2; select length(version()) > 1 as `*` UNION select 2; * diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 2769e284a95..fce2ddfd57a 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -49,9 +49,9 @@ Warnings: Warning 1262 Data truncated, NULL supplied to NOT NULL column 'b' at row 2 Warning 1264 Data truncated for column 'd' at row 3 Warning 1264 Data truncated for column 'c' at row 4 -Warning 1260 Record count is fewer than the column count at row 5 +Warning 1260 Row 5 doesn't contain data for all columns Warning 1264 Data truncated for column 'b' at row 6 -Warning 1261 Record count is more than the column count at row 7 +Warning 1261 Row 7 was truncated; It contained more data than there where input columns Warning 1263 Data truncated, out of range for column 'a' at row 8 select @@warning_count; @@warning_count diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test index 835253e3134..12b81f27147 100644 --- a/mysql-test/t/bdb.test +++ b/mysql-test/t/bdb.test @@ -794,7 +794,7 @@ drop table t1; # Test of multi-table-updates (bug #1980). # -create table t1 ( c char(8) not null ) type=bdb; +create table t1 ( c char(8) not null ) engine=bdb; insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); @@ -803,7 +803,7 @@ alter table t1 add a char(8) not null; alter table t1 add primary key (a,b,c); update t1 set a=c, b=c; -create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=bdb; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) engine=bdb; insert into t2 select * from t1; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 5add6247eaa..b227614e7ae 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -906,7 +906,7 @@ drop table t1; # Test of multi-table-updates (bug #1980). # -create table t1 ( c char(8) not null ) type=innodb; +create table t1 ( c char(8) not null ) engine=innodb; insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'); insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F'); @@ -915,7 +915,7 @@ alter table t1 add a char(8) not null; alter table t1 add primary key (a,b,c); update t1 set a=c, b=c; -create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) type=innodb; +create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) engine=innodb; insert into t2 select * from t1; delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b; @@ -926,19 +926,23 @@ drop table t1,t2; # SET AUTOCOMMIT=1; -create table t1 (a integer auto_increment primary key) type=innodb; +create table t1 (a integer auto_increment primary key) engine=innodb; insert into t1 (a) values (NULL),(NULL); truncate table t1; insert into t1 (a) values (NULL),(NULL); SELECT * from t1; drop table t1; +# +# Test timestamps +# CREATE TABLE t1 (col1 int(1))ENGINE=InnoDB; CREATE TABLE t2 (col1 int(1),stamp TIMESTAMP,INDEX stamp_idx (stamp))ENGINE=InnoDB; insert into t1 values (1),(2),(3); -insert into t2 values (1, 20020204130000),(2, 20020204130000),(4,20020204310000 ); +# Note that timestamp 3 is wrong +insert into t2 values (1, 20020204130000),(2, 20020204130000),(4,20020204310000 ),(5,20020204230000); SELECT col1 FROM t1 UNION SELECT col1 FROM t2 WHERE stamp < '20020204120000' GROUP BY col1; drop table t1,t2; diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 4b69b002342..6f012801972 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -60,8 +60,8 @@ delete from t1, t2, t3 using t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 select count(*) from t1 where id1; select count(*) from t2 where id2; select count(*) from t3 where id3; - drop table t1,t2,t3; + create table t1(id1 int not null primary key, t varchar(100)) pack_keys = 1; create table t2(id2 int not null, t varchar(100), index(id2)) pack_keys = 1; disable_query_log; @@ -288,7 +288,6 @@ drop table t1; # Test multi-update and multi-delete with impossible where -drop table if exists t1, t2; create table t1(id1 smallint(5), field char(5)); create table t2(id2 smallint(5), field char(5)); diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index c926c8e0b0d..1299d73eb99 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -6,7 +6,7 @@ DROP TABLE IF EXISTS t1, `"t"1`; CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); ---exec $MYSQL_DUMP --skip-comments -X test t1 +--exec $MYSQL_DUMP --skip-all --skip-comments -X test t1 DROP TABLE t1; # @@ -33,7 +33,7 @@ DROP TABLE t1; CREATE TABLE t1(a int, b text, c varchar(3)); INSERT INTO t1 VALUES (1, "test", "tes"), (2, "TEST", "TES"); ---exec $MYSQL_DUMP --skip-all -X test t1 +--exec $MYSQL_DUMP --skip-all --skip-comments -X test t1 DROP TABLE t1; # @@ -42,7 +42,7 @@ DROP TABLE t1; CREATE TABLE t1 (`a"b"` char(2)); INSERT INTO t1 VALUES ("1\""), ("\"2"); ---exec $MYSQL_DUMP --skip-all -X test t1 +--exec $MYSQL_DUMP --skip-all --skip-comments -X test t1 DROP TABLE t1; # @@ -51,5 +51,5 @@ DROP TABLE t1; CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'); ---exec $MYSQL_DUMP test t1 +--exec $MYSQL_DUMP --skip-comments test t1 DROP TABLE t1; diff --git a/mysql-test/t/rpl_EE_error.test b/mysql-test/t/rpl_EE_error.test index de69c4897c3..1a1572b48b0 100644 --- a/mysql-test/t/rpl_EE_error.test +++ b/mysql-test/t/rpl_EE_error.test @@ -6,7 +6,7 @@ source include/master-slave.inc; -create table t1 (a int) type=myisam; +create table t1 (a int) engine=myisam; flush tables; system rm ./var/master-data/test/t1.MYI ; drop table t1; @@ -17,7 +17,7 @@ sync_with_master; # Now a real error. connection master; -create table t1 (a int, unique(a)) type=myisam; +create table t1 (a int, unique(a)) engine=myisam; set sql_log_bin=0; insert into t1 values(2); set sql_log_bin=1; diff --git a/mysql-test/t/rpl_multi_update.test b/mysql-test/t/rpl_multi_update.test index c44239594dd..98a199ae412 100644 --- a/mysql-test/t/rpl_multi_update.test +++ b/mysql-test/t/rpl_multi_update.test @@ -1,15 +1,14 @@ source include/master-slave.inc; -drop table if exists t1,t2; CREATE TABLE t1 ( a int unsigned not null auto_increment primary key, b int unsigned, -) TYPE=MyISAM; +) ENGINE=MyISAM; CREATE TABLE t2 ( a int unsigned not null auto_increment primary key, b int unsigned -) TYPE=MyISAM; +) ENGINE=MyISAM; INSERT INTO t1 VALUES (NULL, 0); INSERT INTO t1 SELECT NULL, 0 FROM t1; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index fc986b05fa4..8ce4aa997fc 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -248,6 +248,7 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1; (SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1; create temporary table t1 select a from t1 union select a from t2; +drop temporary table t1; --error 1093 create table t1 select a from t1 union select a from t2; drop table t1,t2; @@ -258,7 +259,6 @@ drop table t1,t2; select length(version()) > 1 as `*` UNION select 2; - # # Test for another bug with UNION and LEFT JOIN # @@ -465,4 +465,3 @@ show status like 'Slow_queries'; select count(*) from t1 where a=7 union select count(*) from t1 where b=13; show status like 'Slow_queries'; drop table t1; - diff --git a/mysys/charset.c b/mysys/charset.c index 4111dd246cb..1fe926a51d6 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -188,9 +188,11 @@ static my_bool create_fromuni(CHARSET_INFO *cs) break; numchars=idx[i].uidx.to-idx[i].uidx.from+1; - idx[i].uidx.tab=(unsigned char*)my_once_alloc(numchars * - sizeof(*idx[i].uidx.tab), - MYF(MY_WME)); + if (!(idx[i].uidx.tab=(uchar*) my_once_alloc(numchars * + sizeof(*idx[i].uidx.tab), + MYF(MY_WME)))) + return TRUE; + bzero(idx[i].uidx.tab,numchars*sizeof(*idx[i].uidx.tab)); for (ch=1; ch < PLANE_SIZE; ch++) @@ -206,8 +208,10 @@ static my_bool create_fromuni(CHARSET_INFO *cs) /* Allocate and fill reverse table for each plane */ n=i; - cs->tab_from_uni= (MY_UNI_IDX*) my_once_alloc(sizeof(MY_UNI_IDX)*(n+1), - MYF(MY_WME)); + if (!(cs->tab_from_uni= (MY_UNI_IDX*) my_once_alloc(sizeof(MY_UNI_IDX)*(n+1), + MYF(MY_WME)))) + return TRUE; + for (i=0; i< n; i++) cs->tab_from_uni[i]= idx[i].uidx; @@ -217,46 +221,64 @@ static my_bool create_fromuni(CHARSET_INFO *cs) } -static void simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from) +static int simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from) { to->number= from->number ? from->number : to->number; if (from->csname) - to->csname= my_once_strdup(from->csname,MYF(MY_WME)); + if (!(to->csname= my_once_strdup(from->csname,MYF(MY_WME)))) + goto err; if (from->name) - to->name= my_once_strdup(from->name,MYF(MY_WME)); + if (!(to->name= my_once_strdup(from->name,MYF(MY_WME)))) + goto err; if (from->comment) - to->comment= my_once_strdup(from->comment,MYF(MY_WME)); + if (!(to->comment= my_once_strdup(from->comment,MYF(MY_WME)))) + goto err; if (from->ctype) { - to->ctype= (uchar*) my_once_memdup((char*) from->ctype, - MY_CS_CTYPE_TABLE_SIZE, MYF(MY_WME)); + if (!(to->ctype= (uchar*) my_once_memdup((char*) from->ctype, + MY_CS_CTYPE_TABLE_SIZE, + MYF(MY_WME)))) + goto err; init_state_maps(to); } if (from->to_lower) - to->to_lower= (uchar*) my_once_memdup((char*) from->to_lower, - MY_CS_TO_LOWER_TABLE_SIZE, MYF(MY_WME)); + if (!(to->to_lower= (uchar*) my_once_memdup((char*) from->to_lower, + MY_CS_TO_LOWER_TABLE_SIZE, + MYF(MY_WME)))) + goto err; + if (from->to_upper) - to->to_upper= (uchar*) my_once_memdup((char*) from->to_upper, - MY_CS_TO_UPPER_TABLE_SIZE, MYF(MY_WME)); + if (!(to->to_upper= (uchar*) my_once_memdup((char*) from->to_upper, + MY_CS_TO_UPPER_TABLE_SIZE, + MYF(MY_WME)))) + goto err; if (from->sort_order) { - to->sort_order= (uchar*) my_once_memdup((char*) from->sort_order, - MY_CS_SORT_ORDER_TABLE_SIZE, - MYF(MY_WME)); + if (!(to->sort_order= (uchar*) my_once_memdup((char*) from->sort_order, + MY_CS_SORT_ORDER_TABLE_SIZE, + MYF(MY_WME)))) + goto err; set_max_sort_char(to); } if (from->tab_to_uni) { uint sz= MY_CS_TO_UNI_TABLE_SIZE*sizeof(uint16); - to->tab_to_uni= (uint16*) my_once_memdup((char*)from->tab_to_uni, sz, - MYF(MY_WME)); - create_fromuni(to); + if (!(to->tab_to_uni= (uint16*) my_once_memdup((char*)from->tab_to_uni, + sz, MYF(MY_WME)))) + goto err; + if (create_fromuni(to)) + goto err; } to->mbmaxlen= 1; + + return 0; + +err: + return 1; } @@ -292,7 +314,8 @@ static int add_collation(CHARSET_INFO *cs) if (!(all_charsets[cs->number]->state & MY_CS_COMPILED)) { simple_cs_init_functions(all_charsets[cs->number]); - simple_cs_copy_data(all_charsets[cs->number],cs); + if (simple_cs_copy_data(all_charsets[cs->number],cs)) + return MY_XML_ERROR; if (simple_cs_is_full(all_charsets[cs->number])) { all_charsets[cs->number]->state |= MY_CS_LOADED; @@ -313,11 +336,14 @@ static int add_collation(CHARSET_INFO *cs) CHARSET_INFO *dst= all_charsets[cs->number]; dst->number= cs->number; if (cs->comment) - dst->comment= my_once_strdup(cs->comment,MYF(MY_WME)); + if (!(dst->comment= my_once_strdup(cs->comment,MYF(MY_WME)))) + return MY_XML_ERROR; if (cs->csname) - dst->csname= my_once_strdup(cs->csname,MYF(MY_WME)); + if (!(dst->csname= my_once_strdup(cs->csname,MYF(MY_WME)))) + return MY_XML_ERROR; if (cs->name) - dst->name= my_once_strdup(cs->name,MYF(MY_WME)); + if (!(dst->name= my_once_strdup(cs->name,MYF(MY_WME)))) + return MY_XML_ERROR; } cs->number= 0; cs->primary_number= 0; diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 2fd7f1fcdee..6ee6167d3c1 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -189,6 +189,14 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, get_key_pack_length(b_length,pack_length,b); next_key_length=key_length-b_length-pack_length; + if (!(nextflag & (SEARCH_PREFIX | SEARCH_UPDATE))) + { + while (a_length && a[a_length-1] == ' ') + a_length--; + while (b_length && b[b_length-1] == ' ') + b_length--; + } + if (piks && (flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && diff --git a/sql-common/client.c b/sql-common/client.c index 374cbb29112..5b702f0e966 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -967,7 +967,8 @@ void mysql_read_default_options(struct st_mysql_options *options, #endif break; case 27: - options->max_allowed_packet= atoi(opt_arg); + if (opt_arg) + options->max_allowed_packet= atoi(opt_arg); break; case 28: /* protocol */ if ((options->protocol = find_type(opt_arg, @@ -1310,7 +1311,9 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) MYSQL * STDCALL mysql_init(MYSQL *mysql) { - mysql_once_init(); + if (mysql_once_init()) + return 0; + if (!mysql) { if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL)))) diff --git a/sql/field.cc b/sql/field.cc index c54e27360b5..4c7e219ab43 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2910,6 +2910,7 @@ static longlong fix_datetime(longlong nr, TIME *time_res, return nr; err: + THD *thd= current_thd; if (thd->count_cuted_fields) { thd->cuted_fields++; @@ -2948,9 +2949,7 @@ int Field_timestamp::store(longlong nr) err: longstore(ptr,(uint32) 0); - if (current_thd->count_cuted_fields) - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, - field_name, 0); + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); return 1; } @@ -5189,7 +5188,7 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)), { uint tmp=(uint) Field_enum::val_int(); if (!tmp || tmp > typelib->count) - val_ptr->set((char*)"",0); + val_ptr->set("", 0, field_charset); else val_ptr->set((const char*) typelib->type_names[tmp-1], (uint) strlen(typelib->type_names[tmp-1]), diff --git a/sql/field.h b/sql/field.h index 223ff4135d4..e3b4bf29fb8 100644 --- a/sql/field.h +++ b/sql/field.h @@ -874,7 +874,9 @@ public: :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg, cs) {} - Field_varstring(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, + Field_varstring(uint32 len_arg,bool maybe_null_arg, + const char *field_name_arg, + struct st_table *table_arg, CHARSET_INFO *cs) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, table_arg, cs) {} @@ -925,10 +927,9 @@ public: :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, table_arg, cs), geom_flag(true), packlength(4) - { - flags|= BLOB_FLAG; - } - } + { + flags|= BLOB_FLAG; + } enum_field_types type() const { return FIELD_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 4e42d629a0f..419eac6d1c3 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -33,11 +33,9 @@ InnoDB */ #include "mysql_priv.h" #include "slave.h" -#include "sql_cache.h" #ifdef HAVE_INNOBASE_DB #include -#include #include #include diff --git a/sql/item.cc b/sql/item.cc index 9a9b8fe26a8..301d2990e0b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -654,10 +654,10 @@ String *Item_param::val_str(String* str) { switch (item_result_type) { case INT_RESULT: - str->set(int_value, default_charset()); + str->set(int_value, &my_charset_bin); return str; case REAL_RESULT: - str->set(real_value, 2, default_charset()); + str->set(real_value, 2, &my_charset_bin); return str; default: return (String*) &str_value; diff --git a/sql/item.h b/sql/item.h index 90a0a706073..c6258518213 100644 --- a/sql/item.h +++ b/sql/item.h @@ -240,6 +240,7 @@ public: st_select_lex *depended_from; Item_ident(const char *db_name_par,const char *table_name_par, const char *field_name_par); + Item_ident::Item_ident(THD *thd, Item_ident &item); const char *full_name() const; bool remove_dependence_processor(byte * arg); diff --git a/sql/item_func.cc b/sql/item_func.cc index 7495987856a..b9cbb38db1a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -317,6 +317,7 @@ void Item_func::print_op(String *str) str->append(')'); } + bool Item_func::eq(const Item *item, bool binary_cmp) const { /* Assume we don't have rtti */ @@ -372,7 +373,7 @@ String *Item_real_func::val_str(String *str) double nr=val(); if (null_value) return 0; /* purecov: inspected */ - str->set(nr,decimals,default_charset()); + str->set(nr,decimals, &my_charset_bin); return str; } @@ -385,16 +386,16 @@ String *Item_num_func::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ if (!unsigned_flag) - str->set(nr,default_charset()); + str->set(nr,&my_charset_bin); else - str->set((ulonglong) nr,default_charset()); + str->set((ulonglong) nr,&my_charset_bin); } else { double nr=val(); if (null_value) return 0; /* purecov: inspected */ - str->set(nr,decimals,default_charset()); + str->set(nr,decimals,&my_charset_bin); } return str; } @@ -421,9 +422,9 @@ String *Item_int_func::val_str(String *str) if (null_value) return 0; if (!unsigned_flag) - str->set(nr,default_charset()); + str->set(nr,&my_charset_bin); else - str->set((ulonglong) nr,default_charset()); + str->set((ulonglong) nr,&my_charset_bin); return str; } @@ -450,16 +451,16 @@ String *Item_num_op::val_str(String *str) if (null_value) return 0; /* purecov: inspected */ if (!unsigned_flag) - str->set(nr,default_charset()); + str->set(nr,&my_charset_bin); else - str->set((ulonglong) nr,default_charset()); + str->set((ulonglong) nr,&my_charset_bin); } else { double nr=val(); if (null_value) return 0; /* purecov: inspected */ - str->set(nr,decimals,default_charset()); + str->set(nr,decimals,&my_charset_bin); } return str; } @@ -1030,9 +1031,9 @@ String *Item_func_min_max::val_str(String *str) if (null_value) return 0; if (!unsigned_flag) - str->set(nr,default_charset()); + str->set(nr,&my_charset_bin); else - str->set((ulonglong) nr,default_charset()); + str->set((ulonglong) nr,&my_charset_bin); return str; } case REAL_RESULT: @@ -1040,7 +1041,7 @@ String *Item_func_min_max::val_str(String *str) double nr=val(); if (null_value) return 0; /* purecov: inspected */ - str->set(nr,decimals,default_charset()); + str->set(nr,decimals,&my_charset_bin); return str; } case STRING_RESULT: @@ -1668,7 +1669,7 @@ String *Item_func_udf_float::val_str(String *str) double nr=val(); if (null_value) return 0; /* purecov: inspected */ - str->set(nr,decimals,default_charset()); + str->set(nr,decimals,&my_charset_bin); return str; } @@ -1689,9 +1690,9 @@ String *Item_func_udf_int::val_str(String *str) if (null_value) return 0; if (!unsigned_flag) - str->set(nr,default_charset()); + str->set(nr,&my_charset_bin); else - str->set((ulonglong) nr,default_charset()); + str->set((ulonglong) nr,&my_charset_bin); return str; } diff --git a/sql/item_func.h b/sql/item_func.h index 739110fd81f..ac67b5a4065 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -717,9 +717,10 @@ public: Item_func_bit_neg(Item *a) :Item_func_bit(a) {} longlong val_int(); const char *func_name() const { return "~"; } - void print(String *str) { Item_func_int::print(str); } + void print(String *str) { Item_func::print(str); } }; + class Item_func_set_last_insert_id :public Item_int_func { public: diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 16c886b558e..3cb03d7ea49 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1582,6 +1582,11 @@ Item_func_format::Item_func_format(Item *org,int dec) :Item_str_func(org) } +/* + TODO: This needs to be fixed for multi-byte character set where numbers + are stored in more than one byte +*/ + String *Item_func_format::val_str(String *str) { double nr =args[0]->val(); @@ -1590,7 +1595,8 @@ String *Item_func_format::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ dec= decimals ? decimals+1 : 0; - str->set(nr,decimals,default_charset()); + /* Here default_charset() is right as this is not an automatic conversion */ + str->set(nr,decimals, default_charset()); #ifdef HAVE_ISNAN if (isnan(nr)) return str; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 7b401b50d4c..bc16fe87c2a 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -344,7 +344,7 @@ void Item_singlerow_subselect::bring_value() exec(); } -double Item_singlerow_subselect::val () +double Item_singlerow_subselect::val() { if (!exec() && !value->null_value) { @@ -358,7 +358,7 @@ double Item_singlerow_subselect::val () } } -longlong Item_singlerow_subselect::val_int () +longlong Item_singlerow_subselect::val_int() { if (!exec() && !value->null_value) { @@ -466,7 +466,7 @@ void Item_exists_subselect::fix_length_and_dec() max_columns= engine->cols(); } -double Item_exists_subselect::val () +double Item_exists_subselect::val() { if (exec()) { @@ -476,7 +476,7 @@ double Item_exists_subselect::val () return (double) value; } -longlong Item_exists_subselect::val_int () +longlong Item_exists_subselect::val_int() { if (exec()) { @@ -493,11 +493,11 @@ String *Item_exists_subselect::val_str(String *str) reset(); return 0; } - str->set(value,default_charset()); + str->set(value,&my_charset_bin); return str; } -double Item_in_subselect::val () +double Item_in_subselect::val() { if (exec()) { @@ -510,7 +510,7 @@ double Item_in_subselect::val () return (double) value; } -longlong Item_in_subselect::val_int () +longlong Item_in_subselect::val_int() { if (exec()) { @@ -536,7 +536,7 @@ String *Item_in_subselect::val_str(String *str) null_value= 1; return 0; } - str->set(value,default_charset()); + str->set(value, &my_charset_bin); return str; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 8d9973e78f8..a31374a3fc3 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -140,7 +140,7 @@ Item_sum_num::val_str(String *str) double nr=val(); if (null_value) return 0; - str->set(nr,decimals,default_charset()); + str->set(nr,decimals, &my_charset_bin); return str; } @@ -477,13 +477,13 @@ Item_sum_hybrid::val_str(String *str) case STRING_RESULT: return &value; case REAL_RESULT: - str->set(sum,decimals,default_charset()); + str->set(sum,decimals, &my_charset_bin); break; case INT_RESULT: if (unsigned_flag) - str->set((ulonglong) sum_int,default_charset()); + str->set((ulonglong) sum_int, &my_charset_bin); else - str->set((longlong) sum_int,default_charset()); + str->set((longlong) sum_int, &my_charset_bin); break; case ROW_RESULT: default: @@ -958,7 +958,7 @@ String *Item_avg_field::val_str(String *str) double nr=Item_avg_field::val(); if (null_value) return 0; - str->set(nr,decimals,default_charset()); + str->set(nr,decimals, &my_charset_bin); return str; } @@ -1006,7 +1006,7 @@ String *Item_variance_field::val_str(String *str) double nr=val(); if (null_value) return 0; - str->set(nr,decimals,default_charset()); + str->set(nr,decimals, &my_charset_bin); return str; } diff --git a/sql/item_sum.h b/sql/item_sum.h index 3fe40ca4c68..8065218df97 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -468,6 +468,7 @@ public: void clear(); longlong val_int(); void reset_field(); + void update_field(); void fix_length_and_dec() { decimals=0; max_length=21; unsigned_flag=1; maybe_null=null_value=0; } }; @@ -500,7 +501,6 @@ class Item_sum_xor :public Item_sum_bit Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} Item_sum_xor(THD *thd, Item_sum_xor &item) :Item_sum_bit(thd, item) {} bool add(); - void update_field(); const char *func_name() const { return "bit_xor"; } Item *copy_or_same(THD* thd); }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index bff9ed94a23..8aa59b4d5d0 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -437,17 +437,11 @@ void kill_mysql(void); void close_connection(THD *thd, uint errcode, bool lock); bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, bool *write_to_binlog); -#ifndef NO_EMBEDDED_ACCESS_CHECKS bool check_access(THD *thd, ulong access, const char *db, ulong *save_priv, bool no_grant, bool no_errors); bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables, bool no_errors); bool check_global_access(THD *thd, ulong want_access); -#else -#define check_access(thd, access, db, save_priv, no_grant, no_errors) false -#define check_table_access(thd, want_access, tables, no_errors) false -#define check_global_access(thd, want_access) false -#endif int mysql_backup_table(THD* thd, TABLE_LIST* table_list); int mysql_restore_table(THD* thd, TABLE_LIST* table_list); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 36fa744e328..2bebec0d3db 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4595,7 +4595,7 @@ The minimum value for this variable is 4096.", {"thread_stack", OPT_THREAD_STACK, "The stack size for each thread.", (gptr*) &thread_stack, (gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, - 1024*32, ~0L, 0, 1024, 0}, + 1024L*128L, ~0L, 0, 1024, 0}, {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE, "Allocation block size for transactions to be stored in binary log", (gptr*) &global_system_variables.trans_alloc_block_size, diff --git a/sql/set_var.cc b/sql/set_var.cc index 66f8c3327a2..88b5d7bfdf0 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -787,9 +787,8 @@ bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex, /* If the string is "", delete old init command */ if (var && (new_length= var->value->str_value.length())) { - if (!(res= my_strdup_with_length(var->value->str_value.ptr(), - new_length, - MYF(0)))) + if (!(res= my_strdup_with_length((byte*) var->value->str_value.ptr(), + new_length, MYF(0)))) return 1; } /* @@ -2501,6 +2500,7 @@ bool sys_var_thd_table_type::check(THD *thd, set_var *var) } return 0; } + value= "unknown"; err: my_error(ER_UNKNOWN_TABLE_ENGINE, MYF(0), value); diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index d6a0c51bdff..4470739cbdd 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -272,8 +272,8 @@ character-set=latin2 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 1d889e6258e..d005150cb89 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -266,8 +266,8 @@ character-set=latin1 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 4798ea55b42..3fd44f9ec69 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -274,8 +274,8 @@ character-set=latin1 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 920ec433da0..6400093a6cf 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -263,8 +263,8 @@ character-set=latin1 "ZLIB: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "ZLIB: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 0c9b5c96308..eb7e6d0508b 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -268,8 +268,8 @@ character-set=latin7 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index a9d3f9b049a..d5a4874a49d 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -263,8 +263,8 @@ character-set=latin1 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 5dfd1173467..5472e824e61 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -263,8 +263,8 @@ character-set=greek "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index d454c51caba..463aaed5760 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -265,8 +265,8 @@ character-set=latin2 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 18715b4930b..204e1f980cc 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -263,8 +263,8 @@ character-set=latin1 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index b034c8f657f..b8b9688fd38 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -265,8 +265,8 @@ character-set=ujis "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index df15d77c075..055d1a0a2c7 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -263,8 +263,8 @@ character-set=euckr "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index b46a52ae2de..735a2583685 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -265,8 +265,8 @@ character-set=latin1 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 3727e49d2ad..2c434da271e 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -265,8 +265,8 @@ character-set=latin1 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 1cb5b384e4b..78fcb2a7993 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -267,8 +267,8 @@ character-set=latin2 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 519f86e284c..528a0d081ff 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -267,8 +267,8 @@ character-set=latin2 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index ae186929898..5224f19b001 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -265,8 +265,8 @@ character-set=koi8r "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 0719b88bec0..904c8f0c8b9 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -258,8 +258,8 @@ character-set=cp1250 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index cb5957fb892..0f5a70fa2c6 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -271,8 +271,8 @@ character-set=latin2 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 0e95efff5aa..845a7da36eb 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -265,8 +265,8 @@ character-set=latin1 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 5edf41e0202..9da0a511ddb 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -263,8 +263,8 @@ character-set=latin1 "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d rad(er) kapades av group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 8dbc2b582c9..7186e0550b2 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -268,8 +268,8 @@ character-set=koi8u "Z_BUF_ERROR: Not enough room in the output buffer for zlib (probably, length of uncompressed data was corrupted)", "Z_DATA_ERROR: Input data was corrupted for zlib", "%d line(s) was(were) cut by group_concat()", -"Record count is fewer than the column count at row %ld", -"Record count is more than the column count at row %ld", +"Row %ld doesn't contain data for all columns", +"Row %ld was truncated; It contained more data than there where input columns", "Data truncated, NULL supplied to NOT NULL column '%s' at row %ld", "Data truncated, out of range for column '%s' at row %ld", "Data truncated for column '%s' at row %ld", diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 8b8115b10db..7b66a851d33 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -58,8 +58,6 @@ #define EXTRA_ACL (1L << 29) #define NO_ACCESS (1L << 30) -#ifndef NO_EMBEDDED_ACCESS_CHECKS - /* Defines to change the above bits to how things are stored in tables This is needed as the 'host' and 'db' table is missing a few privileges @@ -127,8 +125,6 @@ public: char *user,*db; }; - - /* prototypes */ bool hostname_requires_resolving(const char *hostname); @@ -152,7 +148,7 @@ my_bool grant_init(THD *thd); void grant_free(void); void grant_reload(THD *thd); bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, - uint show_command=0, bool dont_print_error=0); + uint show_command, bool dont_print_error); bool check_grant_column (THD *thd,TABLE *table, const char *name, uint length, uint show_command=0); bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table); @@ -165,5 +161,7 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc); int mysql_drop_user(THD *thd, List &list); int mysql_revoke_all(THD *thd, List &list); -#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ - +#ifdef NO_EMBEDDED_ACCESS_CHECKS +#define check_grant(A,B,C,D,E) 0 +#define check_grant_db(A,B) 0 +#endif diff --git a/sql/sql_base.cc b/sql/sql_base.cc index ebb94e11d9d..0101037da85 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1762,7 +1762,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, 'name' of the item which may be used in the select list */ strmake(name_buff, db, sizeof(name_buff)-1); - casedn_str(name_buff); + my_casedn_str(files_charset_info, name_buff); db= name_buff; } diff --git a/sql/sql_client.cc b/sql/sql_client.cc index 1ae9a23a924..905c32a42d9 100644 --- a/sql/sql_client.cc +++ b/sql/sql_client.cc @@ -39,7 +39,8 @@ void my_net_local_init(NET *net) } extern "C" { -void mysql_once_init(void) +int mysql_once_init(void) { + return 0; } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6e6ec025a1f..f6a3308efb7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -51,14 +51,9 @@ extern "C" int gethostname(char *name, int namelen); static int check_for_max_user_connections(THD *thd, USER_CONN *uc); static void decrease_user_connections(USER_CONN *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); -#ifndef NO_EMBEDDED_ACCESS_CHECKS static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); static bool single_table_command_access(THD *thd, ulong privilege, TABLE_LIST *tables, int *res); -#else -#define check_merge_table_access(thd, db, tables) false -#define single_table_command_access(thd, privilege, tables, res) false -#endif static void remove_escape(char *name); static void refresh_status(void); static bool append_file_to_dir(THD *thd, char **filename_ptr, @@ -177,7 +172,6 @@ end: } -#ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if user exist and password supplied is correct. @@ -210,6 +204,11 @@ int check_user(THD *thd, enum enum_server_command command, { DBUG_ENTER("check_user"); +#ifdef NO_EMBEDDED_ACCESS_CHECKS + thd->master_access= GLOBAL_ACLS; // Full rights + return 0; +#else + my_bool opt_secure_auth_local; pthread_mutex_lock(&LOCK_global_system_variables); opt_secure_auth_local= opt_secure_auth; @@ -333,7 +332,8 @@ int check_user(THD *thd, enum enum_server_command command, DBUG_RETURN(-1); } } - send_ok(thd); + else + send_ok(thd); thd->password= test(passwd_len); // remember for error messages /* Ready to handle queries */ DBUG_RETURN(0); @@ -354,11 +354,9 @@ int check_user(THD *thd, enum enum_server_command command, thd->host_or_ip, passwd_len ? ER(ER_YES) : ER(ER_NO)); DBUG_RETURN(-1); +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ } -#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ - - /* Check for maximum allowable user connections, if the mysqld server is started with corresponding variable that is greater then 0. @@ -509,7 +507,6 @@ bool is_update_query(enum enum_sql_command command) return uc_update_queries[command]; } -#ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check if maximum queries per hour limit has been reached returns 0 if OK. @@ -528,6 +525,9 @@ static bool check_mqh(THD *thd, uint check_command) DBUG_ENTER("check_mqh"); DBUG_ASSERT(uc != 0); +#ifdef NO_EMBEDDED_ACCESS_CHECKS + DBUG_RETURN(0); +#else /* If more than a hour since last check, reset resource checking */ if (check_time - uc->intime >= 3600) { @@ -561,12 +561,13 @@ static bool check_mqh(THD *thd, uint check_command) } end: DBUG_RETURN(error); +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ } static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0) { - +#ifndef NO_EMBEDDED_ACCESS_CHECKS (void) pthread_mutex_lock(&LOCK_user_conn); if (lu) // for GRANT { @@ -590,7 +591,8 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0) { for (uint idx=0;idx < hash_user_connections.records; idx++) { - USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections, idx); + USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections, + idx); if (get_them) get_mqh(uc->user,uc->host,uc); uc->questions=0; @@ -599,8 +601,8 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0) } } (void) pthread_mutex_unlock(&LOCK_user_conn); +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ } -#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ /* Perform handshake, authorize client and update thd ACL variables. @@ -1065,7 +1067,6 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) thd->query= thd->memdup_w_gap(buff, length+1, thd->db_length+1); thd->query[length] = '\0'; thd->query_id=query_id++; -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (mqh_used && thd->user_connect && check_mqh(thd, SQLCOM_END)) { thd->net.error = 0; @@ -1073,7 +1074,6 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); break; } -#endif mysql_parse(thd,thd->query,length); close_thread_tables(thd); // Free tables if (thd->is_fatal_error) @@ -1137,12 +1137,10 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT))) DBUG_RETURN(1); -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege,0,0)) goto err; - if (grant_option && check_grant(thd, SELECT_ACL, table_list)) + if (grant_option && check_grant(thd, SELECT_ACL, table_list, 0, 0)) goto err; -#endif thd->free_list = 0; thd->query_length=(uint) strlen(tbl_name); thd->query = tbl_name; @@ -1446,13 +1444,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, my_casedn_str(files_charset_info, table_list.real_name); remove_escape(table_list.real_name); // This can't have wildcards -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,SELECT_ACL,table_list.db,&thd->col_access,0,0)) break; table_list.grant.privilege=thd->col_access; - if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2)) + if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2,0)) break; -#endif /*DONT_ALLOW_SHOW_COMMANDS*/ mysqld_list_fields(thd,&table_list,fields); free_items(thd->free_list); break; @@ -1598,19 +1594,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; case COM_PROCESS_INFO: statistic_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status); -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL)) break; -#endif mysql_log.write(thd,command,NullS); mysqld_list_processes(thd, -#ifndef NO_EMBEDDED_ACCESS_CHECKS thd->master_access & PROCESS_ACL ? - NullS : thd->priv_user -#else - NullS -#endif - ,0); + NullS : thd->priv_user, 0); break; case COM_PROCESS_KILL: { @@ -1814,29 +1803,17 @@ mysql_execute_command(THD *thd) } } } - if (&lex->select_lex != lex->all_selects_list) - { - byte *save= lex->select_lex.table_list.first; - if (lex->sql_command == SQLCOM_CREATE_TABLE) - { - /* Skip first table, which is the table we are creating */ - lex->select_lex.table_list.first= (byte*) (((TABLE_LIST *) save)->next); - } - if (lex->unit.create_total_list(thd, lex, &tables, 0)) - DBUG_VOID_RETURN; - lex->select_lex.table_list.first= save; - } + if (&lex->select_lex != lex->all_selects_list && + lex->sql_command != SQLCOM_CREATE_TABLE && + lex->unit.create_total_list(thd, lex, &tables, 0)) + DBUG_VOID_RETURN; /* When option readonly is set deny operations which change tables. Except for the replication thread and the 'super' users. */ if (opt_readonly && - !(thd->slave_thread -#ifndef NO_EMBEDDED_ACCESS_CHECKS - || (thd->master_access & SUPER_ACL) -#endif - ) && + !(thd->slave_thread || (thd->master_access & SUPER_ACL)) && (uc_update_queries[lex->sql_command] > 0)) { send_error(thd, ER_CANT_UPDATE_WITH_READLOCK); @@ -1848,7 +1825,6 @@ mysql_execute_command(THD *thd) case SQLCOM_SELECT: { select_result *result=lex->result; -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (tables) { res=check_table_access(thd, @@ -1864,7 +1840,6 @@ mysql_execute_command(THD *thd) res=0; break; // Error message is given } -#endif /* In case of single SELECT unit->global_parameters points on first SELECT TODO: move counters to SELECT_LEX @@ -2101,7 +2076,6 @@ mysql_execute_command(THD *thd) { if (!tables->db) tables->db=thd->db; -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege,0,0)) goto error; /* purecov: inspected */ if (grant_option) @@ -2109,12 +2083,11 @@ mysql_execute_command(THD *thd) /* Check that the first table has CREATE privilege */ TABLE_LIST *tmp_table_list=tables->next; tables->next=0; - bool error=check_grant(thd,CREATE_ACL,tables); + bool error=check_grant(thd,CREATE_ACL,tables,0,0); tables->next=tmp_table_list; if (error) goto error; } -#endif if (strlen(tables->real_name) > NAME_LEN) { net_printf(thd,ER_WRONG_TABLE_NAME, tables->real_name); @@ -2137,43 +2110,34 @@ mysql_execute_command(THD *thd) case SQLCOM_CREATE_TABLE: { -#ifndef NO_EMBEDDED_ACCESS_CHECKS + /* Skip first table, which is the table we are creating */ + TABLE_LIST *create_table= tables; + tables= tables->next; + lex->select_lex.table_list.first= (byte*) (tables); + create_table->next= 0; + if (&lex->select_lex != lex->all_selects_list && + lex->unit.create_total_list(thd, lex, &tables, 0)) + DBUG_VOID_RETURN; + ulong want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ? CREATE_TMP_ACL : CREATE_ACL); -#endif - if (!tables->db) - tables->db=thd->db; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (check_access(thd,want_priv,tables->db,&tables->grant.privilege,0,0) || - check_merge_table_access(thd, tables->db, + if (check_access(thd, want_priv, create_table->db, + &create_table->grant.privilege, 0, 0) || + check_merge_table_access(thd, create_table->db, (TABLE_LIST *) lex->create_info.merge_list.first)) goto error; /* purecov: inspected */ - if (grant_option && want_priv != CREATE_TMP_ACL) - { - /* Check that the first table has CREATE privilege */ - TABLE_LIST *tmp_table_list=tables->next; - tables->next=0; - bool error=check_grant(thd, want_priv, tables); - tables->next=tmp_table_list; - if (error) + if (grant_option && want_priv != CREATE_TMP_ACL && + check_grant(thd, want_priv, create_table,0,0)) goto error; - } -#endif - if (strlen(tables->real_name) > NAME_LEN) - { - net_printf(thd, ER_WRONG_TABLE_NAME, tables->alias); - res=0; - break; - } #ifndef HAVE_READLINK lex->create_info.data_file_name=lex->create_info.index_file_name=0; #else /* Fix names if symlinked tables */ if (append_file_to_dir(thd, &lex->create_info.data_file_name, - tables->real_name) || + create_table->real_name) || append_file_to_dir(thd,&lex->create_info.index_file_name, - tables->real_name)) + create_table->real_name)) { res=-1; break; @@ -2197,49 +2161,42 @@ mysql_execute_command(THD *thd) select_result *result; if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && - find_real_table_in_list(tables->next, tables->db, tables->real_name)) + find_real_table_in_list(tables, create_table->db, + create_table->real_name)) { - net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name); + net_printf(thd,ER_UPDATE_TABLE_USED, create_table->real_name); DBUG_VOID_RETURN; } -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (tables->next) - { - if (check_table_access(thd, SELECT_ACL, tables->next,0)) - goto error; // Error message is given - } -#endif + if (tables && check_table_access(thd, SELECT_ACL, tables,0)) + goto error; // Error message is given select_lex->options|= SELECT_NO_UNLOCK; unit->offset_limit_cnt= select_lex->offset_limit; unit->select_limit_cnt= select_lex->select_limit+ select_lex->offset_limit; if (unit->select_limit_cnt < select_lex->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // No limit + unit->select_limit_cnt= HA_POS_ERROR; // No limit - /* Skip first table, which is the table we are creating */ - lex->select_lex.table_list.first= - (byte*) (((TABLE_LIST *) lex->select_lex.table_list.first)->next); - if (!(res=open_and_lock_tables(thd,tables->next))) + if (!(res=open_and_lock_tables(thd,tables))) { - if ((result=new select_create(tables->db ? tables->db : thd->db, - tables->real_name, &lex->create_info, + res= -1; // If error + if ((result=new select_create(create_table->db, + create_table->real_name, + &lex->create_info, lex->create_list, lex->key_list, select_lex->item_list,lex->duplicates))) res=handle_select(thd, lex, result); - else - res= -1; } } else // regular create { if (lex->name) - res= mysql_create_like_table(thd, tables, &lex->create_info, + res= mysql_create_like_table(thd, create_table, &lex->create_info, (Table_ident *)lex->name); else { - res= mysql_create_table(thd,tables->db ? tables->db : thd->db, - tables->real_name, &lex->create_info, + res= mysql_create_table(thd,create_table->db, + create_table->real_name, &lex->create_info, lex->create_list, lex->key_list,0,0,0); // do logging } @@ -2251,12 +2208,10 @@ mysql_execute_command(THD *thd) case SQLCOM_CREATE_INDEX: if (!tables->db) tables->db=thd->db; -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege,0,0)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd,INDEX_ACL,tables)) + if (grant_option && check_grant(thd,INDEX_ACL,tables,0,0)) goto error; -#endif thd->slow_command=TRUE; if (end_active_trans(thd)) res= -1; @@ -2324,10 +2279,9 @@ mysql_execute_command(THD *thd) goto error; /* purecov: inspected */ if (!tables->db) tables->db=thd->db; -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (grant_option) { - if (check_grant(thd,ALTER_ACL,tables)) + if (check_grant(thd,ALTER_ACL,tables,0,0)) goto error; if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL)) { // Rename of table @@ -2336,11 +2290,10 @@ mysql_execute_command(THD *thd) tmp_table.real_name=lex->name; tmp_table.db=select_lex->db; tmp_table.grant.privilege=priv; - if (check_grant(thd,INSERT_ACL | CREATE_ACL,tables)) + if (check_grant(thd,INSERT_ACL | CREATE_ACL,tables,0,0)) goto error; } } -#endif /* Don't yet allow changing of symlinks with ALTER TABLE */ lex->create_info.data_file_name=lex->create_info.index_file_name=0; /* ALTER TABLE ends previous transaction */ @@ -2368,7 +2321,6 @@ mysql_execute_command(THD *thd) TABLE_LIST *table; if (check_db_used(thd,tables)) goto error; -#ifndef NO_EMBEDDED_ACCESS_CHECKS for (table=tables ; table ; table=table->next->next) { if (check_access(thd, ALTER_ACL | DROP_ACL, table->db, @@ -2382,14 +2334,13 @@ mysql_execute_command(THD *thd) old_list=table[0]; new_list=table->next[0]; old_list.next=new_list.next=0; - if (check_grant(thd,ALTER_ACL,&old_list) || + if (check_grant(thd,ALTER_ACL,&old_list,0,0) || (!test_all_bits(table->next->grant.privilege, INSERT_ACL | CREATE_ACL) && - check_grant(thd,INSERT_ACL | CREATE_ACL, &new_list))) + check_grant(thd,INSERT_ACL | CREATE_ACL, &new_list,0,0))) goto error; } } -#endif query_cache_invalidate3(thd, tables, 0); if (end_active_trans(thd)) res= -1; @@ -2543,12 +2494,10 @@ mysql_execute_command(THD *thd) res= -1; break; case SQLCOM_UPDATE_MULTI: -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,UPDATE_ACL,tables->db,&tables->grant.privilege,0,0)) goto error; - if (grant_option && check_grant(thd,UPDATE_ACL,tables)) + if (grant_option && check_grant(thd,UPDATE_ACL,tables,0,0)) goto error; -#endif if (select_lex->item_list.elements != lex->value_list.elements) { send_error(thd,ER_WRONG_VALUE_COUNT); @@ -2578,16 +2527,12 @@ mysql_execute_command(THD *thd) case SQLCOM_REPLACE: case SQLCOM_INSERT: { -#ifndef NO_EMBEDDED_ACCESS_CHECKS my_bool update=(lex->value_list.elements ? UPDATE_ACL : 0); ulong privilege= (lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL | update); if (single_table_command_access(thd, privilege, tables, &res)) goto error; -#else - my_bool update=(lex->value_list.elements ? 1 : 0); -#endif if (select_lex->item_list.elements != lex->value_list.elements) { send_error(thd,ER_WRONG_VALUE_COUNT); @@ -2607,7 +2552,6 @@ mysql_execute_command(THD *thd) Check that we have modify privileges for the first table and select privileges for the rest */ -#ifndef NO_EMBEDDED_ACCESS_CHECKS { ulong privilege= (lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL); @@ -2615,18 +2559,17 @@ mysql_execute_command(THD *thd) tables->next=0; if (check_access(thd, privilege, tables->db,&tables->grant.privilege,0,0) || - (grant_option && check_grant(thd, privilege, tables))) + (grant_option && check_grant(thd, privilege, tables,0,0))) goto error; tables->next=save_next; if ((res=check_table_access(thd, SELECT_ACL, save_next,0))) goto error; } -#endif /* Fix lock for first table */ if (tables->lock_type == TL_WRITE_DELAYED) - tables->lock_type == TL_WRITE; + tables->lock_type = TL_WRITE; /* Don't unlock tables until command is written to binary log */ select_lex->options|= SELECT_NO_UNLOCK; @@ -2661,12 +2604,10 @@ mysql_execute_command(THD *thd) break; } case SQLCOM_TRUNCATE: -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege,0,0)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd,DELETE_ACL,tables)) + if (grant_option && check_grant(thd,DELETE_ACL,tables,0,0)) goto error; -#endif /* Don't allow this within a transaction because we want to use re-generate table @@ -2680,12 +2621,10 @@ mysql_execute_command(THD *thd) break; case SQLCOM_DELETE: { -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (single_table_command_access(thd, DELETE_ACL, tables, &res)) goto error; // Set privilege for the WHERE clause tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); -#endif res = mysql_delete(thd,tables, select_lex->where, (ORDER*) select_lex->order_list.first, select_lex->select_limit, select_lex->options); @@ -2807,12 +2746,10 @@ mysql_execute_command(THD *thd) case SQLCOM_DROP_INDEX: if (!tables->db) tables->db=thd->db; -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege,0,0)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd,INDEX_ACL,tables)) + if (grant_option && check_grant(thd,INDEX_ACL,tables,0,0)) goto error; -#endif if (end_active_trans(thd)) res= -1; else @@ -2830,18 +2767,11 @@ mysql_execute_command(THD *thd) break; #endif case SQLCOM_SHOW_PROCESSLIST: -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL)) break; -#endif mysqld_list_processes(thd, -#ifndef NO_EMBEDDED_ACCESS_CHECKS thd->master_access & PROCESS_ACL ? NullS : - thd->priv_user -#else - NullS -#endif - ,lex->verbose); + thd->priv_user,lex->verbose); break; case SQLCOM_SHOW_TABLE_TYPES: res= mysqld_show_table_types(thd); @@ -2867,10 +2797,8 @@ mysql_execute_command(THD *thd) DBUG_VOID_RETURN; #else { -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (grant_option && check_access(thd, FILE_ACL, any_db,0,0,0)) goto error; -#endif res= mysqld_show_logs(thd); break; } @@ -2894,7 +2822,6 @@ mysql_execute_command(THD *thd) net_printf(thd,ER_WRONG_DB_NAME, db); goto error; } -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) goto error; /* purecov: inspected */ if (!thd->col_access && check_grant_db(thd,db)) @@ -2905,7 +2832,6 @@ mysql_execute_command(THD *thd) db); goto error; } -#endif /* grant is checked in mysqld_show_tables */ if (select_lex->options & SELECT_DESCRIBE) res= mysqld_extend_show_tables(thd,db, @@ -2939,13 +2865,11 @@ mysql_execute_command(THD *thd) } remove_escape(db); // Fix escaped '_' remove_escape(tables->real_name); -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,&thd->col_access,0,0)) goto error; /* purecov: inspected */ tables->grant.privilege=thd->col_access; - if (grant_option && check_grant(thd,SELECT_ACL,tables,2)) + if (grant_option && check_grant(thd,SELECT_ACL,tables,2,0)) goto error; -#endif res= mysqld_show_fields(thd,tables, (lex->wild ? lex->wild->ptr() : NullS), lex->verbose); @@ -2968,13 +2892,11 @@ mysql_execute_command(THD *thd) remove_escape(tables->real_name); if (!tables->db) tables->db=thd->db; -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) goto error; /* purecov: inspected */ tables->grant.privilege=thd->col_access; - if (grant_option && check_grant(thd,SELECT_ACL,tables,2)) + if (grant_option && check_grant(thd,SELECT_ACL,tables,2,0)) goto error; -#endif res= mysqld_show_keys(thd,tables); break; } @@ -2985,7 +2907,6 @@ mysql_execute_command(THD *thd) case SQLCOM_LOAD: { -#ifndef NO_EMBEDDED_ACCESS_CHECKS uint privilege= (lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL); @@ -3002,11 +2923,11 @@ mysql_execute_command(THD *thd) send_error(thd,ER_NOT_ALLOWED_COMMAND); goto error; } - if (check_access(thd,privilege,tables->db,&tables->grant.privilege,0,0) || - grant_option && check_grant(thd,privilege,tables)) + if (check_access(thd,privilege,tables->db,&tables->grant.privilege,0, + 0) || + grant_option && check_grant(thd,privilege,tables,0,0)) goto error; } -#endif /*NO_EMBEDDED_ACCESS_CHECKS*/ res=mysql_load(thd, lex->exchange, tables, lex->field_list, lex->duplicates, (bool) lex->local_file, lex->lock_option); break; @@ -3250,7 +3171,7 @@ mysql_execute_command(THD *thd) if (grant_option && check_grant(thd, (lex->grant | lex->grant_tot_col | GRANT_ACL), - tables)) + tables,0,0)) goto error; if (!(res = mysql_table_grant(thd,tables,lex->users_list, lex->columns, lex->grant, @@ -3458,7 +3379,6 @@ error: } -#ifndef NO_EMBEDDED_ACCESS_CHECKS /* Check grants for commands which work only with one table and all other tables belong to subselects. @@ -3479,23 +3399,23 @@ static bool single_table_command_access(THD *thd, ulong privilege, TABLE_LIST *tables, int *res) { - if (check_access(thd, privilege, tables->db, &tables->grant.privilege,0,0)) - return 1; + if (check_access(thd, privilege, tables->db, &tables->grant.privilege,0,0)) + return 1; - // Show only 1 table for check_grant - TABLE_LIST *subselects_tables= tables->next; - tables->next= 0; - if (grant_option && check_grant(thd, privilege, tables)) - return 1; + // Show only 1 table for check_grant + TABLE_LIST *subselects_tables= tables->next; + tables->next= 0; + if (grant_option && check_grant(thd, privilege, tables, 0, 0)) + return 1; - // check rights on tables of subselect (if exists) - if (subselects_tables) - { - tables->next= subselects_tables; - if ((*res= check_table_access(thd, SELECT_ACL, subselects_tables,0))) - return 1; - } - return 0; + // check rights on tables of subselect (if exists) + if (subselects_tables) + { + tables->next= subselects_tables; + if ((*res= check_table_access(thd, SELECT_ACL, subselects_tables,0))) + return 1; + } + return 0; } @@ -3538,6 +3458,9 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_RETURN(TRUE); /* purecov: tested */ } +#ifdef NO_EMBEDDED_ACCESS_CHECKS + DBUG_RETURN(0); +#else if ((thd->master_access & want_access) == want_access) { /* @@ -3587,6 +3510,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, thd->priv_host, db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -3611,6 +3535,9 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, bool check_global_access(THD *thd, ulong want_access) { +#ifdef NO_EMBEDDED_ACCESS_CHECKS + return 0; +#else char command[128]; if ((thd->master_access & want_access)) return 0; @@ -3618,6 +3545,7 @@ bool check_global_access(THD *thd, ulong want_access) net_printf(thd,ER_SPECIFIC_ACCESS_DENIED_ERROR, command); return 1; +#endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -3682,7 +3610,6 @@ static bool check_merge_table_access(THD *thd, char *db, return error; } -#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ static bool check_db_used(THD *thd,TABLE_LIST *tables) { @@ -3941,9 +3868,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) else { mysql_execute_command(thd); -#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ query_cache_end_of_result(&thd->net); -#endif } } } @@ -3951,9 +3876,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) { DBUG_PRINT("info",("Command aborted. Fatal_error: %d", thd->is_fatal_error)); -#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ query_cache_abort(&thd->net); -#endif } thd->proc_info="freeing items"; free_items(thd->free_list); /* Free strings used by items */ @@ -4005,7 +3928,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, { if (type == FIELD_TYPE_TIMESTAMP) { - net_printf(&thd->net, ER_INVALID_DEFAULT, field_name); + net_printf(thd, ER_INVALID_DEFAULT, field_name); DBUG_RETURN(1); } else if (default_value->type() == Item::NULL_ITEM) @@ -4674,10 +4597,8 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, UNLOCK_ACTIVE_MI; } #endif -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (options & REFRESH_USER_RESOURCES) reset_mqh(thd,(LEX_USER *) NULL); -#endif if (write_to_binlog) *write_to_binlog= tmp_write_to_binlog; return result; @@ -4712,18 +4633,14 @@ void kill_one_thread(THD *thd, ulong id) VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (tmp) { -#ifndef NO_EMBEDDED_ACCESS_CHECKS if ((thd->master_access & SUPER_ACL) || !strcmp(thd->user,tmp->user)) -#endif { tmp->awake(1 /*prepare to die*/); error=0; } -#ifndef NO_EMBEDDED_ACCESS_CHECKS else error=ER_KILL_DENIED_ERROR; -#endif pthread_mutex_unlock(&tmp->LOCK_delete); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 790b80eb127..58e6dbff1ed 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -544,7 +544,7 @@ static bool mysql_test_insert_fields(PREP_STMT *stmt, if (check_access(thd,privilege,table_list->db, &table_list->grant.privilege,0,0) || - (grant_option && check_grant(thd,privilege,table_list))) + (grant_option && check_grant(thd,privilege,table_list,0,0))) DBUG_RETURN(1); #endif if (open_and_lock_tables(thd, table_list)) @@ -599,7 +599,7 @@ static bool mysql_test_upd_fields(PREP_STMT *stmt, TABLE_LIST *table_list, #ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_access(thd,UPDATE_ACL,table_list->db, &table_list->grant.privilege,0,0) || - (grant_option && check_grant(thd,UPDATE_ACL,table_list))) + (grant_option && check_grant(thd,UPDATE_ACL,table_list,0,0))) DBUG_RETURN(1); #endif if (open_and_lock_tables(thd, table_list)) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b2224d3ca9d..16b9a341ee5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1134,8 +1134,6 @@ JOIN::exec() simple_order= simple_group; skip_sort_order= 0; } - if (!order && !no_order) - order=group_list; if (order && (const_tables == tables || ((simple_order || skip_sort_order) && @@ -2487,8 +2485,6 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, join_tab[i].table->map); } } - if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64)) - return TRUE; /* fill keyuse with found key parts */ for ( ; field != end ; field++) add_key_part(keyuse,field); @@ -3255,7 +3251,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, if (j->type == JT_CONST) j->table->const_table= 1; else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY | - HA_END_SPACE_KEY)) != HA_NOSAME) || + HA_END_SPACE_KEY)) != HA_NOSAME) || keyparts != keyinfo->key_parts || null_ref_key) { /* Must read with repeat */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 9f54b838e41..7dc537768f3 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -596,7 +596,8 @@ int multi_update::prepare(List ¬_used_values, { TABLE *table=table_ref->table; if (!(tables_to_update & table->map) && - check_dup(table_ref->db, table_ref->real_name, update_tables)) + find_real_table_in_list(update_tables, table_ref->db, + table_ref->real_name)) table->no_cache= 1; // Disable row cache } DBUG_RETURN(thd->is_fatal_error != 0); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ef71036206a..c847c6958a0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -579,9 +579,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %left SHIFT_LEFT SHIFT_RIGHT %left '-' '+' %left '*' '/' '%' DIV_SYM MOD_SYM -%left NEG '~' %left XOR %left '^' +%left NEG '~' %right NOT %right BINARY COLLATE_SYM diff --git a/sql/table.cc b/sql/table.cc index fc1b8a13497..bc437f250b9 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1234,11 +1234,12 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res) char *get_field(MEM_ROOT *mem, Field *field) { - char buff[MAX_FIELD_WIDTH] *to; + char buff[MAX_FIELD_WIDTH], *to; String str(buff,sizeof(buff),&my_charset_bin); uint length; field->val_str(&str,&str); + length= str.length(); if (!length || !(to= (char*) alloc_root(mem,length+1))) return NullS; memcpy(to,str.ptr(),(uint) length); From 5be2b8b11a731a31960fe94af67aaf5173115390 Mon Sep 17 00:00:00 2001 From: "bar@bar.intranet.mysql.r18.ru" <> Date: Fri, 19 Dec 2003 19:12:11 +0400 Subject: [PATCH 88/89] Fix for Bug#2151: "USE db" affected the character set of further CREATE DATABASEs, which should have not happened. --- BitKeeper/etc/logging_ok | 1 + mysql-test/r/ctype_create.result | 20 ++++++++++++++++ mysql-test/t/ctype_create.test | 39 ++++++++++++++++++++++++++++++++ mysys/charset2html.c | 2 +- sql/sql_db.cc | 8 +++---- 5 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 mysql-test/r/ctype_create.result create mode 100644 mysql-test/t/ctype_create.test diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 57b624db888..db4ad62f23b 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -12,6 +12,7 @@ antony@ltantony.rdg.cyberkinetica.homeunix.net arjen@co3064164-a.bitbike.com arjen@fred.bitbike.com arjen@george.bitbike.com +bar@bar.intranet.mysql.r18.ru bar@bar.mysql.r18.ru bar@bar.udmsearch.izhnet.ru bar@gw.udmsearch.izhnet.ru diff --git a/mysql-test/r/ctype_create.result b/mysql-test/r/ctype_create.result new file mode 100644 index 00000000000..b9146b5818f --- /dev/null +++ b/mysql-test/r/ctype_create.result @@ -0,0 +1,20 @@ +SET @@character_set_server=latin5; +CREATE DATABASE db1 DEFAULT CHARACTER SET cp1251; +USE db1; +CREATE DATABASE db2; +SHOW CREATE DATABASE db1; +Database Create Database +db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET cp1251 */ +SHOW CREATE DATABASE db2; +Database Create Database +db2 CREATE DATABASE `db2` /*!40100 DEFAULT CHARACTER SET latin5 */ +DROP DATABASE db2; +USE db1; +CREATE TABLE t1 (a char(10)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=cp1251 +DROP TABLE t1; +DROP DATABASE db1; diff --git a/mysql-test/t/ctype_create.test b/mysql-test/t/ctype_create.test new file mode 100644 index 00000000000..a4858898535 --- /dev/null +++ b/mysql-test/t/ctype_create.test @@ -0,0 +1,39 @@ +# +# Test for various CREATE statements and character sets +# + + +# Check that the database charset is taken from server charset by default: +# - Change local character_set_server variable to latin5. +# - Create database with and without CHARACTER SET specification. +# At the same time check fix for the +# Bug#2151: +# "USE db" with non-default character set should never affect +# further CREATE DATABASEs. + + +SET @@character_set_server=latin5; +CREATE DATABASE db1 DEFAULT CHARACTER SET cp1251; +USE db1; +CREATE DATABASE db2; + +# +# This should be cp1251 +# +SHOW CREATE DATABASE db1; + +# +# This should take the default latin5 value from server level. +# +SHOW CREATE DATABASE db2; +DROP DATABASE db2; + +# +# Check that table value uses database level by default +# +USE db1; +CREATE TABLE t1 (a char(10)); +SHOW CREATE TABLE t1; + +DROP TABLE t1; +DROP DATABASE db1; diff --git a/mysys/charset2html.c b/mysys/charset2html.c index c6112bfeb9e..64021689bea 100644 --- a/mysys/charset2html.c +++ b/mysys/charset2html.c @@ -81,7 +81,7 @@ static void print_cs(CHARSET_INFO *cs) printf("",clr ? "DDDDDD" : "EEEE99"); printf("%02X",ch[i].cod); printf("%04X",ch[i].uni); - printf("%d",ch[i].srt); + printf("%02X",ch[i].srt); printf("%s%s%s%s%s%s%s%s", ch[i].ctp & _U ? "U" : "", diff --git a/sql/sql_db.cc b/sql/sql_db.cc index c61e6800cfa..c4a3f5367d1 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -62,7 +62,7 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) ulong length; CHARSET_INFO *cs= (create && create->default_table_charset) ? create->default_table_charset : - thd->variables.collation_database; + thd->variables.collation_server; length= my_sprintf(buf,(buf, "default-character-set=%s\ndefault-collation=%s\n", cs->csname,cs->name)); @@ -101,7 +101,7 @@ static bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) uint nbytes; bzero((char*) create,sizeof(*create)); - create->default_table_charset= global_system_variables.collation_database; + create->default_table_charset= thd->variables.collation_server; if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) >= 0) { IO_CACHE cache; @@ -290,7 +290,7 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { thd->db_charset= (create_info && create_info->default_table_charset) ? create_info->default_table_charset : - global_system_variables.collation_database; + thd->variables.collation_server; thd->variables.collation_database= thd->db_charset; } @@ -663,7 +663,7 @@ bool mysql_change_db(THD *thd, const char *name) load_db_opt(thd, path, &create); thd->db_charset= create.default_table_charset ? create.default_table_charset : - global_system_variables.collation_database; + thd->variables.collation_server; thd->variables.collation_database= thd->db_charset; DBUG_RETURN(0); } From 7dfcc949d6c21980fc4b9f437090985fc3723c01 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Fri, 19 Dec 2003 17:15:54 +0200 Subject: [PATCH 89/89] after merge fixes --- mysql-test/r/auto_increment.result | 4 +- mysql-test/r/type_decimal.result | 123 +++++++++++++++++++++++++++++ mysql-test/r/type_enum.result | 1 + mysql-test/t/auto_increment.test | 2 +- mysql-test/t/type_decimal.test | 3 +- 5 files changed, 129 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index df14fc74f05..7a7faf0db9a 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -119,7 +119,7 @@ a 1 2 drop table t1; -create table t1 (a int not null auto_increment primary key) /*!40102 type=heap */; +create table t1 (a int not null auto_increment primary key) /*!40102 engine=heap */; insert into t1 values (NULL); insert into t1 values (-1); select last_insert_id(); @@ -128,8 +128,8 @@ last_insert_id() insert into t1 values (NULL); select * from t1; a --1 1 +-1 2 drop table t1; create table t1 (i tinyint unsigned not null auto_increment primary key); diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index fa4cd231129..97d81d77722 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -446,6 +446,39 @@ CREATE TABLE t1 (a_dec DECIMAL(-1,1)); ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '-1,1))' at line 1 create table t1(a decimal(7,3)); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); +Warnings: +Warning 1263 Data truncated, out of range for column 'a' at row 27 +Warning 1263 Data truncated, out of range for column 'a' at row 30 +Warning 1263 Data truncated, out of range for column 'a' at row 31 +Warning 1263 Data truncated, out of range for column 'a' at row 32 +Warning 1263 Data truncated, out of range for column 'a' at row 33 +Warning 1263 Data truncated, out of range for column 'a' at row 34 +Warning 1263 Data truncated, out of range for column 'a' at row 35 +Warning 1263 Data truncated, out of range for column 'a' at row 36 +Warning 1263 Data truncated, out of range for column 'a' at row 37 +Warning 1263 Data truncated, out of range for column 'a' at row 38 +Warning 1263 Data truncated, out of range for column 'a' at row 39 +Warning 1263 Data truncated, out of range for column 'a' at row 40 +Warning 1263 Data truncated, out of range for column 'a' at row 41 +Warning 1263 Data truncated, out of range for column 'a' at row 42 +Warning 1263 Data truncated, out of range for column 'a' at row 43 +Warning 1263 Data truncated, out of range for column 'a' at row 44 +Warning 1263 Data truncated, out of range for column 'a' at row 45 +Warning 1263 Data truncated, out of range for column 'a' at row 46 +Warning 1263 Data truncated, out of range for column 'a' at row 47 +Warning 1263 Data truncated, out of range for column 'a' at row 48 +Warning 1263 Data truncated, out of range for column 'a' at row 49 +Warning 1263 Data truncated, out of range for column 'a' at row 50 +Warning 1263 Data truncated, out of range for column 'a' at row 51 +Warning 1263 Data truncated, out of range for column 'a' at row 52 +Warning 1263 Data truncated, out of range for column 'a' at row 53 +Warning 1263 Data truncated, out of range for column 'a' at row 54 +Warning 1263 Data truncated, out of range for column 'a' at row 55 +Warning 1263 Data truncated, out of range for column 'a' at row 56 +Warning 1263 Data truncated, out of range for column 'a' at row 57 +Warning 1263 Data truncated, out of range for column 'a' at row 58 +Warning 1263 Data truncated, out of range for column 'a' at row 59 +Warning 1263 Data truncated, out of range for column 'a' at row 60 select * from t1; a 1.000 @@ -511,6 +544,51 @@ a drop table t1; create table t1(a decimal(7,3) unsigned); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); +Warnings: +Warning 1263 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 6 +Warning 1263 Data truncated, out of range for column 'a' at row 9 +Warning 1263 Data truncated, out of range for column 'a' at row 12 +Warning 1263 Data truncated, out of range for column 'a' at row 15 +Warning 1263 Data truncated, out of range for column 'a' at row 18 +Warning 1263 Data truncated, out of range for column 'a' at row 21 +Warning 1263 Data truncated, out of range for column 'a' at row 24 +Warning 1263 Data truncated, out of range for column 'a' at row 25 +Warning 1263 Data truncated, out of range for column 'a' at row 26 +Warning 1263 Data truncated, out of range for column 'a' at row 27 +Warning 1263 Data truncated, out of range for column 'a' at row 28 +Warning 1263 Data truncated, out of range for column 'a' at row 29 +Warning 1263 Data truncated, out of range for column 'a' at row 30 +Warning 1263 Data truncated, out of range for column 'a' at row 31 +Warning 1263 Data truncated, out of range for column 'a' at row 32 +Warning 1263 Data truncated, out of range for column 'a' at row 33 +Warning 1263 Data truncated, out of range for column 'a' at row 34 +Warning 1263 Data truncated, out of range for column 'a' at row 35 +Warning 1263 Data truncated, out of range for column 'a' at row 36 +Warning 1263 Data truncated, out of range for column 'a' at row 37 +Warning 1263 Data truncated, out of range for column 'a' at row 38 +Warning 1263 Data truncated, out of range for column 'a' at row 39 +Warning 1263 Data truncated, out of range for column 'a' at row 40 +Warning 1263 Data truncated, out of range for column 'a' at row 41 +Warning 1263 Data truncated, out of range for column 'a' at row 42 +Warning 1263 Data truncated, out of range for column 'a' at row 43 +Warning 1263 Data truncated, out of range for column 'a' at row 44 +Warning 1263 Data truncated, out of range for column 'a' at row 45 +Warning 1263 Data truncated, out of range for column 'a' at row 46 +Warning 1263 Data truncated, out of range for column 'a' at row 47 +Warning 1263 Data truncated, out of range for column 'a' at row 48 +Warning 1263 Data truncated, out of range for column 'a' at row 49 +Warning 1263 Data truncated, out of range for column 'a' at row 50 +Warning 1263 Data truncated, out of range for column 'a' at row 51 +Warning 1263 Data truncated, out of range for column 'a' at row 52 +Warning 1263 Data truncated, out of range for column 'a' at row 53 +Warning 1263 Data truncated, out of range for column 'a' at row 54 +Warning 1263 Data truncated, out of range for column 'a' at row 55 +Warning 1263 Data truncated, out of range for column 'a' at row 56 +Warning 1263 Data truncated, out of range for column 'a' at row 57 +Warning 1263 Data truncated, out of range for column 'a' at row 58 +Warning 1263 Data truncated, out of range for column 'a' at row 59 +Warning 1263 Data truncated, out of range for column 'a' at row 60 select * from t1; a 1.000 @@ -576,6 +654,51 @@ a drop table t1; create table t1(a decimal(7,3) zerofill); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); +Warnings: +Warning 1263 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 6 +Warning 1263 Data truncated, out of range for column 'a' at row 9 +Warning 1263 Data truncated, out of range for column 'a' at row 12 +Warning 1263 Data truncated, out of range for column 'a' at row 15 +Warning 1263 Data truncated, out of range for column 'a' at row 18 +Warning 1263 Data truncated, out of range for column 'a' at row 21 +Warning 1263 Data truncated, out of range for column 'a' at row 24 +Warning 1263 Data truncated, out of range for column 'a' at row 25 +Warning 1263 Data truncated, out of range for column 'a' at row 26 +Warning 1263 Data truncated, out of range for column 'a' at row 27 +Warning 1263 Data truncated, out of range for column 'a' at row 28 +Warning 1263 Data truncated, out of range for column 'a' at row 29 +Warning 1263 Data truncated, out of range for column 'a' at row 30 +Warning 1263 Data truncated, out of range for column 'a' at row 31 +Warning 1263 Data truncated, out of range for column 'a' at row 32 +Warning 1263 Data truncated, out of range for column 'a' at row 33 +Warning 1263 Data truncated, out of range for column 'a' at row 34 +Warning 1263 Data truncated, out of range for column 'a' at row 35 +Warning 1263 Data truncated, out of range for column 'a' at row 36 +Warning 1263 Data truncated, out of range for column 'a' at row 37 +Warning 1263 Data truncated, out of range for column 'a' at row 38 +Warning 1263 Data truncated, out of range for column 'a' at row 39 +Warning 1263 Data truncated, out of range for column 'a' at row 40 +Warning 1263 Data truncated, out of range for column 'a' at row 41 +Warning 1263 Data truncated, out of range for column 'a' at row 42 +Warning 1263 Data truncated, out of range for column 'a' at row 43 +Warning 1263 Data truncated, out of range for column 'a' at row 44 +Warning 1263 Data truncated, out of range for column 'a' at row 45 +Warning 1263 Data truncated, out of range for column 'a' at row 46 +Warning 1263 Data truncated, out of range for column 'a' at row 47 +Warning 1263 Data truncated, out of range for column 'a' at row 48 +Warning 1263 Data truncated, out of range for column 'a' at row 49 +Warning 1263 Data truncated, out of range for column 'a' at row 50 +Warning 1263 Data truncated, out of range for column 'a' at row 51 +Warning 1263 Data truncated, out of range for column 'a' at row 52 +Warning 1263 Data truncated, out of range for column 'a' at row 53 +Warning 1263 Data truncated, out of range for column 'a' at row 54 +Warning 1263 Data truncated, out of range for column 'a' at row 55 +Warning 1263 Data truncated, out of range for column 'a' at row 56 +Warning 1263 Data truncated, out of range for column 'a' at row 57 +Warning 1263 Data truncated, out of range for column 'a' at row 58 +Warning 1263 Data truncated, out of range for column 'a' at row 59 +Warning 1263 Data truncated, out of range for column 'a' at row 60 select * from t1; a 0001.000 diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index db14a658bd2..fe8f78453b7 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -1650,6 +1650,7 @@ select * from t1; a drop table t1; +set names latin1; create table t1 (a enum(0xE4, '1', '2') not null default 0xE4); show columns from t1; Field Type Null Key Default Extra diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index bb9394dd6d2..99a75889431 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -85,7 +85,7 @@ insert into t1 values (NULL); select * from t1; drop table t1; -create table t1 (a int not null auto_increment primary key) /*!40102 type=heap */; +create table t1 (a int not null auto_increment primary key) /*!40102 engine=heap */; insert into t1 values (NULL); insert into t1 values (-1); select last_insert_id(); diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index 098d76b759f..cddb0347b7e 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -248,7 +248,7 @@ CREATE TABLE t1 (a_dec DECIMAL(-1,1)); # # Zero prepend overflow bug # - +--disable-warnings create table t1(a decimal(7,3)); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); select * from t1; @@ -259,5 +259,6 @@ select * from t1; drop table t1; create table t1(a decimal(7,3) zerofill); insert into t1 values ('1'),('+1'),('-1'),('0000000001'),('+0000000001'),('-0000000001'),('10'),('+10'),('-10'),('0000000010'),('+0000000010'),('-0000000010'),('100'),('+100'),('-100'),('0000000100'),('+0000000100'),('-0000000100'),('1000'),('+1000'),('-1000'),('0000001000'),('+0000001000'),('-0000001000'),('10000'),('+10000'),('-10000'),('0000010000'),('+0000010000'),('-0000010000'),('100000'),('+100000'),('-100000'),('0000100000'),('+0000100000'),('-0000100000'),('1000000'),('+1000000'),('-1000000'),('0001000000'),('+0001000000'),('-0001000000'),('10000000'),('+10000000'),('-10000000'),('0010000000'),('+0010000000'),('-0010000000'),('100000000'),('+100000000'),('-100000000'),('0100000000'),('+0100000000'),('-0100000000'),('1000000000'),('+1000000000'),('-1000000000'),('1000000000'),('+1000000000'),('-1000000000'); +--enable-warnings select * from t1; drop table t1;