From 850cfe786a39c6088be8647cc8d2b35c765841aa Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Nov 2005 14:47:33 +0100 Subject: [PATCH 01/29] Fixed BUG#14643: Stored Procedure: Continuing after failed var. initialization crashes server. Make sure variables are initialized to something (like null) when the default initialization fails and a continue handler is in effect. mysql-test/r/sp.result: New test case for BUG#14643. mysql-test/t/sp.test: New test case for BUG#14643. sql/sp_head.cc: Make sure variables are initialized to something (like null) when the default initialization fails and a continue handler is in effect. If this also fails (out of memory), we have to abort without letting the handler catch. --- mysql-test/r/sp.result | 36 ++++++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 44 ++++++++++++++++++++++++++++++++++++++++++ sql/sp_head.cc | 20 +++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index d50e6dd3751..ab80545590c 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3617,4 +3617,40 @@ count(*) drop table t3, t4| drop procedure bug14210| set @@session.max_heap_table_size=default| +drop procedure if exists bug14643_1| +drop procedure if exists bug14643_2| +create procedure bug14643_1() +begin +declare continue handler for sqlexception select 'boo' as 'Handler'; +begin +declare v int default x; +if v = 1 then +select 1; +else +select 2; +end if; +end; +end| +create procedure bug14643_2() +begin +declare continue handler for sqlexception select 'boo' as 'Handler'; +case x +when 1 then +select 1; +else +select 2; +end case; +end| +call bug14643_1()| +Handler +boo +2 +2 +call bug14643_2()| +Handler +boo +2 +2 +drop procedure bug14643_1| +drop procedure bug14643_2| drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index eaf69c0ab03..edfa09c0e7c 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4541,6 +4541,50 @@ drop table t3, t4| drop procedure bug14210| set @@session.max_heap_table_size=default| + +# +# BUG#14643: Stored Procedure: Continuing after failed var. initialization +# crashes server. +# +--disable_warnings +drop procedure if exists bug14643_1| +drop procedure if exists bug14643_2| +--enable_warnings + +create procedure bug14643_1() +begin + declare continue handler for sqlexception select 'boo' as 'Handler'; + + begin + declare v int default x; + + if v = 1 then + select 1; + else + select 2; + end if; + end; +end| + +create procedure bug14643_2() +begin + declare continue handler for sqlexception select 'boo' as 'Handler'; + + case x + when 1 then + select 1; + else + select 2; + end case; +end| + +call bug14643_1()| +call bug14643_2()| + +drop procedure bug14643_1| +drop procedure bug14643_2| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sp_head.cc b/sql/sp_head.cc index abc66ce0b21..8d6ce3336f2 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2031,6 +2031,26 @@ sp_instr_set::exec_core(THD *thd, uint *nextp) { int res= thd->spcont->set_item_eval(thd, m_offset, &m_value, m_type); + if (res < 0 && + thd->spcont->get_item(m_offset) == NULL && + thd->spcont->found_handler_here()) + { + /* + Failed to evaluate the value, the variable is still not initialized, + and a handler has been found. Set to null so we can continue. + */ + Item *it= new Item_null(); + + if (!it || thd->spcont->set_item_eval(thd, m_offset, &it, m_type) < 0) + { /* If this also failed, we have to abort */ + sp_rcontext *spcont= thd->spcont; + + thd->spcont= 0; /* Avoid handlers */ + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + spcont->clear_handler(); + thd->spcont= spcont; + } + } *nextp = m_ip+1; return res; } From a2e5a9f9235b6cbb851c5cf357bb34113d25e030 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Nov 2005 16:36:06 +0400 Subject: [PATCH 02/29] Bug#14406 GRANTS ON objects with non-ascii names borked after FLUSH PRIVILEGES ps_grant.result: Fixing result order. grant.result: Adding test case, fixing result order. grant.test: Adding test case. sql_acl.cc: Fixed that my_charset_latin1 was incorrectly used instead of system_charset_info. This problem was previously fixed by Ingo in 5.0. This patch is basically a backport of the same changes into 4.1. sql/sql_acl.cc: Bug#14406 GRANTS ON objects with non-ascii names borked after FLUSH PRIVILEGES Fixed that my_charset_latin1 was incorrectly used instead of system_charset_info. This problem was previously fixed by Ingo in 5.0. This patch is basically a backport of the same changes into 4.1. mysql-test/t/grant.test: Adding test case. mysql-test/r/grant.result: Adding test case, fixing result order. mysql-test/r/ps_grant.result: Fixing result order. --- mysql-test/r/grant.result | 27 ++++++++-- mysql-test/r/ps_grant.result | 6 +-- mysql-test/t/grant.test | 12 +++++ sql/sql_acl.cc | 95 ++++++++++++++++++------------------ 4 files changed, 87 insertions(+), 53 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index a50293752ec..0a406c1ffc2 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -351,10 +351,10 @@ GRANT USAGE ON *.* TO 'grant_user'@'localhost' GRANT INSERT (a, d, c, b) ON `test`.`t1` TO 'grant_user'@'localhost' select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv; Host Db User Table_name Column_name Column_priv -localhost test grant_user t1 c Insert localhost test grant_user t1 b Insert -localhost test grant_user t1 a Insert localhost test grant_user t1 d Insert +localhost test grant_user t1 a Insert +localhost test grant_user t1 c Insert revoke ALL PRIVILEGES on t1 from grant_user@localhost; show grants for grant_user@localhost; Grants for grant_user@localhost @@ -377,9 +377,9 @@ show grants for mysqltest_3@localhost; Grants for mysqltest_3@localhost GRANT USAGE ON *.* TO 'mysqltest_3'@'localhost' GRANT SELECT (b) ON `mysqltest_1`.`t2` TO 'mysqltest_3'@'localhost' -GRANT SELECT (c) ON `mysqltest_2`.`t1` TO 'mysqltest_3'@'localhost' GRANT UPDATE (a) ON `mysqltest_1`.`t1` TO 'mysqltest_3'@'localhost' GRANT UPDATE (d) ON `mysqltest_2`.`t2` TO 'mysqltest_3'@'localhost' +GRANT SELECT (c) ON `mysqltest_2`.`t1` TO 'mysqltest_3'@'localhost' update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1; ERROR 42000: UPDATE command denied to user 'mysqltest_3'@'localhost' for column 'q' in table 't1' update mysqltest_1.t1, mysqltest_2.t2 set d=20 where d=1; @@ -443,3 +443,24 @@ flush privileges; set @user123="non-existent"; select * from mysql.db where user=@user123; Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv +set names koi8r; +create database ÂÄ; +grant select on ÂÄ.* to root@localhost; +select hex(Db) from mysql.db where Db='ÂÄ'; +hex(Db) +D0B1D0B4 +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost' +flush privileges; +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost' +drop database ÂÄ; +revoke all privileges on ÂÄ.* from root@localhost; +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +set names latin1; diff --git a/mysql-test/r/ps_grant.result b/mysql-test/r/ps_grant.result index f883bef8591..1d66bad7eb7 100644 --- a/mysql-test/r/ps_grant.result +++ b/mysql-test/r/ps_grant.result @@ -32,19 +32,19 @@ identified by 'looser' ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' drop table mysqltest.t9 ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' prepare s_t1 from 'select a as my_col from t1' ; execute s_t1 ; my_col diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index b0de62e679c..039e41dcf34 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -409,4 +409,16 @@ flush privileges; set @user123="non-existent"; select * from mysql.db where user=@user123; +set names koi8r; +create database ÂÄ; +grant select on ÂÄ.* to root@localhost; +select hex(Db) from mysql.db where Db='ÂÄ'; +show grants for root@localhost; +flush privileges; +show grants for root@localhost; +drop database ÂÄ; +revoke all privileges on ÂÄ.* from root@localhost; +show grants for root@localhost; +set names latin1; + # End of 4.1 tests diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 47c6343bc3b..1ade6ce3064 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -903,7 +903,7 @@ static void acl_update_user(const char *user, const char *host, { if (!acl_user->host.hostname && !host[0] || acl_user->host.hostname && - !my_strcasecmp(&my_charset_latin1, host, acl_user->host.hostname)) + !my_strcasecmp(system_charset_info, host, acl_user->host.hostname)) { acl_user->access=privileges; if (mqh->bits & 1) @@ -982,7 +982,7 @@ static void acl_update_db(const char *user, const char *host, const char *db, { if (!acl_db->host.hostname && !host[0] || acl_db->host.hostname && - !my_strcasecmp(&my_charset_latin1, host, acl_db->host.hostname)) + !my_strcasecmp(system_charset_info, host, acl_db->host.hostname)) { if (!acl_db->db && !db[0] || acl_db->db && !strcmp(db,acl_db->db)) @@ -1128,7 +1128,7 @@ static void init_check_host(void) DBUG_ENTER("init_check_host"); VOID(my_init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), acl_users.elements,1)); - VOID(hash_init(&acl_check_hosts,&my_charset_latin1,acl_users.elements,0,0, + VOID(hash_init(&acl_check_hosts,system_charset_info,acl_users.elements,0,0, (hash_get_key) check_get_key,0,0)); if (!allow_all_hosts) { @@ -1144,7 +1144,7 @@ static void init_check_host(void) { // Check if host already exists acl_host_and_ip *acl=dynamic_element(&acl_wild_hosts,j, acl_host_and_ip *); - if (!my_strcasecmp(&my_charset_latin1, + if (!my_strcasecmp(system_charset_info, acl_user->host.hostname, acl->hostname)) break; // already stored } @@ -1225,7 +1225,7 @@ bool check_change_password(THD *thd, const char *host, const char *user, } if (!thd->slave_thread && (strcmp(thd->user,user) || - my_strcasecmp(&my_charset_latin1, host, thd->priv_host))) + my_strcasecmp(system_charset_info, host, thd->priv_host))) { if (check_access(thd, UPDATE_ACL, "mysql",0,1,0)) return(1); @@ -1434,7 +1434,7 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, return (tmp & host->ip_mask) == host->ip; } return (!host->hostname || - (hostname && !wild_case_compare(&my_charset_latin1, + (hostname && !wild_case_compare(system_charset_info, hostname,host->hostname)) || (ip && !wild_compare(ip,host->hostname,0))); } @@ -1447,7 +1447,7 @@ bool hostname_requires_resolving(const char *hostname) int namelen= strlen(hostname); int lhlen= strlen(my_localhost); if ((namelen == lhlen) && - !my_strnncoll(&my_charset_latin1, (const uchar *)hostname, namelen, + !my_strnncoll(system_charset_info, (const uchar *)hostname, namelen, (const uchar *)my_localhost, strlen(my_localhost))) return FALSE; for (; (cur=*hostname); hostname++) @@ -1481,8 +1481,8 @@ static bool update_user_table(THD *thd, TABLE *table, DBUG_ENTER("update_user_table"); DBUG_PRINT("enter",("user: %s host: %s",user,host)); - table->field[0]->store(host,(uint) strlen(host), &my_charset_latin1); - table->field[1]->store(user,(uint) strlen(user), &my_charset_latin1); + table->field[0]->store(host,(uint) strlen(host), system_charset_info); + table->field[1]->store(user,(uint) strlen(user), system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, @@ -1494,7 +1494,7 @@ static bool update_user_table(THD *thd, TABLE *table, DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,record[1]); - table->field[2]->store(new_password, new_password_len, &my_charset_latin1); + table->field[2]->store(new_password, new_password_len, system_charset_info); if ((error=table->file->update_row(table->record[1],table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ @@ -1559,8 +1559,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, password=combo.password.str; } - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0], 0, (byte*) table->field[0]->ptr, @@ -1579,18 +1579,18 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, old_row_exists = 0; restore_record(table,default_values); // cp empty row from default_values table->field[0]->store(combo.host.str,combo.host.length, - &my_charset_latin1); + system_charset_info); table->field[1]->store(combo.user.str,combo.user.length, - &my_charset_latin1); + system_charset_info); table->field[2]->store(password, password_len, - &my_charset_latin1); + system_charset_info); } else { old_row_exists = 1; store_record(table,record[1]); // Save copy for update if (combo.password.str) // If password given - table->field[2]->store(password, password_len, &my_charset_latin1); + table->field[2]->store(password, password_len, system_charset_info); else if (!rights && !revoke_grant && thd->lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && !thd->lex->mqh.bits) { @@ -1637,15 +1637,15 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (thd->lex->ssl_cipher) table->field[next_field+1]->store(thd->lex->ssl_cipher, strlen(thd->lex->ssl_cipher), - &my_charset_latin1); + system_charset_info); if (thd->lex->x509_issuer) table->field[next_field+2]->store(thd->lex->x509_issuer, strlen(thd->lex->x509_issuer), - &my_charset_latin1); + system_charset_info); if (thd->lex->x509_subject) table->field[next_field+3]->store(thd->lex->x509_subject, strlen(thd->lex->x509_subject), - &my_charset_latin1); + system_charset_info); break; case SSL_TYPE_NOT_SPECIFIED: break; @@ -1750,9 +1750,9 @@ static int replace_db_table(TABLE *table, const char *db, DBUG_RETURN(-1); } - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, (byte*) table->field[0]->ptr, @@ -1766,9 +1766,9 @@ static int replace_db_table(TABLE *table, const char *db, } old_row_exists = 0; restore_record(table,default_values); // cp empty row from default_values - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); } else { @@ -1880,7 +1880,7 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u, key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3; hash_key = (char*) alloc_root(&memex,key_length); strmov(strmov(strmov(hash_key,user)+1,db)+1,tname); - (void) hash_init(&hash_columns,&my_charset_latin1, + (void) hash_init(&hash_columns,system_charset_info, 0,0,0, (hash_get_key) get_key_column,0,0); } @@ -1916,17 +1916,17 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) privs = fix_rights_for_table(privs); cols = fix_rights_for_column(cols); - (void) hash_init(&hash_columns,&my_charset_latin1, + (void) hash_init(&hash_columns,system_charset_info, 0,0,0, (hash_get_key) get_key_column,0,0); if (cols) { int key_len; col_privs->field[0]->store(host.hostname, host.hostname ? (uint) strlen(host.hostname) : 0, - &my_charset_latin1); - col_privs->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - col_privs->field[2]->store(user,(uint) strlen(user), &my_charset_latin1); - col_privs->field[3]->store(tname,(uint) strlen(tname), &my_charset_latin1); + system_charset_info); + col_privs->field[1]->store(db,(uint) strlen(db), system_charset_info); + col_privs->field[2]->store(user,(uint) strlen(user), system_charset_info); + col_privs->field[3]->store(tname,(uint) strlen(tname), system_charset_info); key_len=(col_privs->field[0]->pack_length()+ col_privs->field[1]->pack_length()+ col_privs->field[2]->pack_length()+ @@ -2032,10 +2032,10 @@ static int replace_column_table(GRANT_TABLE *g_t, byte key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_column_table"); - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); key_length=(table->field[0]->pack_length()+ table->field[1]->pack_length()+ table->field[2]->pack_length()+ table->field[3]->pack_length()); key_copy(key,table,0,key_length); @@ -2053,7 +2053,7 @@ static int replace_column_table(GRANT_TABLE *g_t, bool old_row_exists=0; key_restore(table,key,0,key_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), - &my_charset_latin1); + system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr, @@ -2071,7 +2071,7 @@ static int replace_column_table(GRANT_TABLE *g_t, restore_record(table,default_values); // Get empty record key_restore(table,key,0,key_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), - &my_charset_latin1); + system_charset_info); } else { @@ -2143,7 +2143,8 @@ static int replace_column_table(GRANT_TABLE *g_t, { GRANT_COLUMN *grant_column = NULL; char colum_name_buf[HOSTNAME_LENGTH+1]; - String column_name(colum_name_buf,sizeof(colum_name_buf),&my_charset_latin1); + String column_name(colum_name_buf,sizeof(colum_name_buf), + system_charset_info); privileges&= ~rights; table->field[6]->store((longlong) @@ -2213,10 +2214,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } restore_record(table,default_values); // Get empty record - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); store_record(table,record[1]); // store at pos 1 table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, @@ -2261,7 +2262,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } } - table->field[4]->store(grantor,(uint) strlen(grantor), &my_charset_latin1); + table->field[4]->store(grantor,(uint) strlen(grantor), system_charset_info); table->field[6]->store((longlong) store_table_rights); table->field[7]->store((longlong) store_col_rights); rights=fix_rights_for_table(store_table_rights); @@ -2727,7 +2728,7 @@ static my_bool grant_load(TABLE_LIST *tables) DBUG_ENTER("grant_load"); grant_option = FALSE; - (void) hash_init(&column_priv_hash,&my_charset_latin1, + (void) hash_init(&column_priv_hash,system_charset_info, 0,0,0, (hash_get_key) get_grant_table, (hash_free_key) free_grant_table,0); init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); @@ -3206,7 +3207,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!(host=acl_user->host.hostname)) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) break; } if (counter == acl_users.elements) @@ -3340,7 +3341,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { want_access=acl_db->access; if (want_access) @@ -3400,7 +3401,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) user= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, + !my_strcasecmp(system_charset_info, lex_user->host.str, grant_table->host.hostname)) { ulong table_access= grant_table->privs; From f455634cba9c7b949583e64f08b40de6b16e85b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 Nov 2005 11:52:58 +0400 Subject: [PATCH 03/29] Fix for bug #15047: "server crash when compiling without transaction support". sql/sql_class.h: Fix for bug #15047: "server crash when compiling without transaction support". - set xid_state.xa_state to XA_NOTR in absence of transactional engines, as we check it in the end_trans() which is always called from the ha_enable_transaction(). --- sql/sql_class.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/sql_class.h b/sql/sql_class.h index ed6f5732ca8..9395252310b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1229,14 +1229,16 @@ public: free_root(&mem_root,MYF(MY_KEEP_PREALLOC)); #endif } -#ifdef USING_TRANSACTIONS st_transactions() { +#ifdef USING_TRANSACTIONS bzero((char*)this, sizeof(*this)); xid_state.xid.null(); init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); - } +#else + xid_state.xa_state= XA_NOTR; #endif + } } transaction; Field *dupp_field; #ifndef __WIN__ From 95b92b4369cd85c3c04d1910e30333e862f416fa Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 Nov 2005 12:27:58 +0100 Subject: [PATCH 04/29] Bug #14514 Creating table with packed key fails silently - Backport from 5.0 include/my_base.h: Rename HA_CREATE_FROM_ENGINE to HA_OPTION_CREATE_FROM_ENGINE, ie. it's a bit in the table_options variable mysql-test/r/ndb_basic.result: Add test result mysql-test/t/ndb_basic.test: Add test case for bug14514 sql/ha_ndbcluster.cc: Use new bitmask for table_options to detect if create from engine sql/handler.cc: Use new bit for create from engine --- include/my_base.h | 2 +- mysql-test/r/ndb_basic.result | 4 ++++ mysql-test/t/ndb_basic.test | 8 ++++++++ sql/ha_ndbcluster.cc | 2 +- sql/handler.cc | 2 +- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index d702ec45140..271e7cd23ba 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -231,6 +231,7 @@ enum ha_base_keytype { #define HA_OPTION_CHECKSUM 32 #define HA_OPTION_DELAY_KEY_WRITE 64 #define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */ +#define HA_OPTION_CREATE_FROM_ENGINE 256 #define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */ #define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */ @@ -241,7 +242,6 @@ enum ha_base_keytype { #define HA_CREATE_TMP_TABLE 4 #define HA_CREATE_CHECKSUM 8 #define HA_CREATE_DELAY_KEY_WRITE 64 -#define HA_CREATE_FROM_ENGINE 128 /* Bits in flag to _status */ diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 3712fa2b5ca..42b5a39d3d8 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -667,3 +667,7 @@ counter datavalue 57 newval 58 newval drop table t1; +CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; +select * from t1; +b +drop table t1; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index 144e466d937..c8cf5823500 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -606,4 +606,12 @@ select * from t1 order by counter; drop table t1; +# +# BUG#14514 Creating table with packed key fails silently +# + +CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; +select * from t1; +drop table t1; + # End of 4.1 tests diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 608dc3eaa54..5391f0dedd0 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3711,7 +3711,7 @@ int ha_ndbcluster::create(const char *name, const void *data, *pack_data; const char **key_names= form->keynames.type_names; char name2[FN_HEADLEN]; - bool create_from_engine= (info->table_options & HA_CREATE_FROM_ENGINE); + bool create_from_engine= (info->table_options & HA_OPTION_CREATE_FROM_ENGINE); DBUG_ENTER("create"); DBUG_PRINT("enter", ("name: %s", name)); diff --git a/sql/handler.cc b/sql/handler.cc index e6bc1496a00..e166f9885fc 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1382,7 +1382,7 @@ int ha_create_table_from_engine(THD* thd, DBUG_RETURN(3); update_create_info_from_table(&create_info, &table); - create_info.table_options|= HA_CREATE_FROM_ENGINE; + create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE; if (lower_case_table_names == 2 && !(table.file->table_flags() & HA_FILE_BASED)) From 31ea9f945d2acfa8e0dec18df8ae7094d7ca62b0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 Nov 2005 16:09:26 +0400 Subject: [PATCH 05/29] Fix for bug#14780 memory leak for mysql 4.1.14 with openssl enabled --- sql-common/client.c | 6 +++++- vio/vio.c | 2 +- vio/vio_priv.h | 1 - vio/viossl.c | 19 ------------------- 4 files changed, 6 insertions(+), 22 deletions(-) diff --git a/sql-common/client.c b/sql-common/client.c index 3979b9304f7..3a598832253 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1487,11 +1487,15 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , static void mysql_ssl_free(MYSQL *mysql __attribute__((unused))) { + struct st_VioSSLConnectorFd *st= + (struct st_VioSSLConnectorFd*) mysql->connector_fd; my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); + my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); + if (st) + SSL_CTX_free(st->ssl_context); my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR)); mysql->options.ssl_key = 0; mysql->options.ssl_cert = 0; diff --git a/vio/vio.c b/vio/vio.c index 427c52e29d3..6174acd7024 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -83,7 +83,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type, #ifdef HAVE_OPENSSL if (type == VIO_TYPE_SSL) { - vio->viodelete =vio_ssl_delete; + vio->viodelete =vio_delete; vio->vioerrno =vio_ssl_errno; vio->read =vio_ssl_read; vio->write =vio_ssl_write; diff --git a/vio/vio_priv.h b/vio/vio_priv.h index c1c78cc6efa..eb495025ddd 100644 --- a/vio/vio_priv.h +++ b/vio/vio_priv.h @@ -28,7 +28,6 @@ void vio_ignore_timeout(Vio *vio, uint which, uint timeout); #ifdef HAVE_OPENSSL #include "my_net.h" /* needed because of struct in_addr */ -void vio_ssl_delete(Vio* vio); int vio_ssl_read(Vio *vio,gptr buf, int size); int vio_ssl_write(Vio *vio,const gptr buf,int size); void vio_ssl_timeout(Vio *vio, uint which, uint timeout); diff --git a/vio/viossl.c b/vio/viossl.c index a3a2e7190bd..62145fe5006 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -69,25 +69,6 @@ report_errors() DBUG_VOID_RETURN; } -/* - Delete a vio object - - SYNPOSIS - vio_ssl_delete() - vio Vio object. May be 0. -*/ - - -void vio_ssl_delete(Vio * vio) -{ - if (vio) - { - if (vio->type != VIO_CLOSED) - vio_close(vio); - my_free((gptr) vio,MYF(0)); - } -} - int vio_ssl_errno(Vio *vio __attribute__((unused))) { From b118282377a7b80b8d50b996d896bd5424d5d52e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Nov 2005 11:56:53 +0100 Subject: [PATCH 06/29] Fixed BUG#13729 Stored procedures: packet error after exception handled Don't set thd->is_fatal_error in sql_update for duplicate key errors. mysql-test/r/sp.result: New test case for BUG#13729. mysql-test/r/sp_trans.result: New test case for BUG#14840. mysql-test/t/sp.test: New test case for BUG#13729. mysql-test/t/sp_trans.test: New test case for BUG#14840. sql/sql_update.cc: Don't set thd->is_fatal_error if it's a duplicate key error. --- mysql-test/r/sp.result | 18 ++++++++++ mysql-test/r/sp_trans.result | 56 +++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 27 +++++++++++++++ mysql-test/t/sp_trans.test | 64 ++++++++++++++++++++++++++++++++++++ sql/sql_update.cc | 14 ++++++-- 5 files changed, 177 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 93332af21a9..5e1d21eaec6 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -3667,4 +3667,22 @@ call bug14845()| a 0 drop procedure bug14845| +drop procedure if exists bug13729| +drop table if exists t3| +create table t3 (s1 int, primary key (s1))| +insert into t3 values (1),(2)| +create procedure bug13729() +begin +declare continue handler for sqlexception select 55; +update t3 set s1 = 1; +end| +call bug13729()| +55 +55 +select * from t3| +s1 +1 +2 +drop procedure bug13729| +drop table t3| drop table t1,t2; diff --git a/mysql-test/r/sp_trans.result b/mysql-test/r/sp_trans.result index bb742d0d3d7..8f2bd9985fc 100644 --- a/mysql-test/r/sp_trans.result +++ b/mysql-test/r/sp_trans.result @@ -369,3 +369,59 @@ drop procedure bug13825_0| drop procedure bug13825_1| drop procedure bug13825_2| drop table t1, t2| +drop table if exists t3| +drop procedure if exists bug14840_1| +drop procedure if exists bug14840_2| +create table t3 +( +x int, +y int, +primary key (x) +) engine=InnoDB| +create procedure bug14840_1() +begin +declare err int default 0; +declare continue handler for sqlexception +set err = err + 1; +start transaction; +update t3 set x = 1, y = 42 where x = 2; +insert into t3 values (3, 4711); +if err > 0 then +rollback; +else +commit; +end if; +select * from t3; +end| +create procedure bug14840_2() +begin +declare err int default 0; +declare continue handler for sqlexception +begin +set err = err + 1; +select err as 'Ping'; +end; +update t3 set x = 1, y = 42 where x = 2; +update t3 set x = 1, y = 42 where x = 2; +insert into t3 values (3, 4711); +select * from t3; +end| +insert into t3 values (1, 3), (2, 5)| +call bug14840_1()| +x y +1 3 +2 5 +delete from t3| +insert into t3 values (1, 3), (2, 5)| +call bug14840_2()| +Ping +1 +Ping +2 +x y +1 3 +2 5 +3 4711 +drop procedure bug14840_1| +drop procedure bug14840_2| +drop table t3| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 5ad2b9287aa..8fa3ae46de4 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4594,6 +4594,33 @@ end| call bug14845()| drop procedure bug14845| +# +# BUG#13729: Stored procedures: packet error after exception handled +# +--disable_warnings +drop procedure if exists bug13729| +drop table if exists t3| +--enable_warnings + +create table t3 (s1 int, primary key (s1))| + +insert into t3 values (1),(2)| + +create procedure bug13729() +begin + declare continue handler for sqlexception select 55; + + update t3 set s1 = 1; +end| + +call bug13729()| +# Used to cause Packets out of order +select * from t3| + +drop procedure bug13729| +drop table t3| + + # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/sp_trans.test b/mysql-test/t/sp_trans.test index d72eaf5dca0..308d4ad5c33 100644 --- a/mysql-test/t/sp_trans.test +++ b/mysql-test/t/sp_trans.test @@ -355,6 +355,70 @@ drop procedure bug13825_2| drop table t1, t2| +# +# BUG#14840: CONTINUE handler problem +# +--disable_warnings +drop table if exists t3| +drop procedure if exists bug14840_1| +drop procedure if exists bug14840_2| +--enable_warnings + +create table t3 +( + x int, + y int, + primary key (x) +) engine=InnoDB| + +# This used to hang the client since the insert returned with an +# error status (left over from the update) even though it succeeded, +# which caused the execution to end at that point. +create procedure bug14840_1() +begin + declare err int default 0; + declare continue handler for sqlexception + set err = err + 1; + + start transaction; + update t3 set x = 1, y = 42 where x = 2; + insert into t3 values (3, 4711); + if err > 0 then + rollback; + else + commit; + end if; + select * from t3; +end| + +# A simpler (non-transactional) case: insert at select should be done +create procedure bug14840_2() +begin + declare err int default 0; + declare continue handler for sqlexception + begin + set err = err + 1; + select err as 'Ping'; + end; + + update t3 set x = 1, y = 42 where x = 2; + update t3 set x = 1, y = 42 where x = 2; + insert into t3 values (3, 4711); + select * from t3; +end| + +insert into t3 values (1, 3), (2, 5)| +call bug14840_1()| + +delete from t3| +insert into t3 values (1, 3), (2, 5)| +call bug14840_2()| + +drop procedure bug14840_1| +drop procedure bug14840_2| +drop table t3| + + # # BUG#NNNN: New bug synopsis # diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 039aa0f71fa..50f8e35a9e9 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -465,7 +465,12 @@ int mysql_update(THD *thd, } else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) { - thd->fatal_error(); // Force error message + /* + If (ignore && error == HA_ERR_FOUND_DUPP_KEY) we don't have to + do anything; otherwise... + */ + if (error != HA_ERR_FOUND_DUPP_KEY) + thd->fatal_error(); /* Other handler errors are fatal */ table->file->print_error(error,MYF(0)); error= 1; break; @@ -1259,7 +1264,12 @@ bool multi_update::send_data(List ¬_used_values) updated--; if (!ignore || error != HA_ERR_FOUND_DUPP_KEY) { - thd->fatal_error(); // Force error message + /* + If (ignore && error == HA_ERR_FOUND_DUPP_KEY) we don't have to + do anything; otherwise... + */ + if (error != HA_ERR_FOUND_DUPP_KEY) + thd->fatal_error(); /* Other handler errors are fatal */ table->file->print_error(error,MYF(0)); DBUG_RETURN(1); } From c2421d3f0dffe87a272483712a4c6a455b1b3ecd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 17:30:25 +1100 Subject: [PATCH 07/29] BUG#15215 mysqld fails at start-up because of illegal reply from mgmd In the rare circumstance where a mysqld connects to a mgm server, then the mgm server goes away before a node id can be allocated, it was possible to get an Error in mgm protocol parser error message. ndb/src/common/mgmcommon/ConfigRetriever.cpp: When allocating node id, retry connecting to a management server if it goes away. ndb/src/mgmapi/mgmapi.cpp: Treat Eof and NoLine results from the parser as a sign that we should disconnect from this management server. It's up to the caller to work out if they want to try again. --- ndb/src/common/mgmcommon/ConfigRetriever.cpp | 6 ++++++ ndb/src/mgmapi/mgmapi.cpp | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp index b3d0221fedb..278bf2b8ec7 100644 --- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp +++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp @@ -341,9 +341,15 @@ ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds) { while (1) { + if(!ndb_mgm_is_connected(m_handle)) + if(!ndb_mgm_connect(m_handle, 0, 0, 0)) + goto next; + int res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type); if(res >= 0) return _ownNodeId= (Uint32)res; + + next: if (no_retries == 0) break; no_retries--; diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 9bb238ca90b..a69a61dcda7 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -336,10 +336,16 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow *command_reply, const Properties* p = parser.parse(ctx, session); if (p == NULL){ if(!ndb_mgm_is_connected(handle)) { - return NULL; + DBUG_RETURN(NULL); } else { + if(ctx.m_status==Parser_t::Eof + || ctx.m_status==Parser_t::NoLine) + { + ndb_mgm_disconnect(handle); + DBUG_RETURN(NULL); + } /** * Print some info about why the parser returns NULL */ From 2665fb75d6490dacbcee36ee3e3e7fe371da95c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Nov 2005 00:04:53 +1100 Subject: [PATCH 08/29] small build fix for some compilers ndb/src/common/mgmcommon/ConfigRetriever.cpp: build fix for some compilers --- ndb/src/common/mgmcommon/ConfigRetriever.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp index 278bf2b8ec7..a44550da48b 100644 --- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp +++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp @@ -336,6 +336,7 @@ ConfigRetriever::setNodeId(Uint32 nodeid) Uint32 ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds) { + int res; _ownNodeId= 0; if(m_handle != 0) { @@ -345,7 +346,7 @@ ConfigRetriever::allocNodeId(int no_retries, int retry_delay_in_seconds) if(!ndb_mgm_connect(m_handle, 0, 0, 0)) goto next; - int res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type); + res= ndb_mgm_alloc_nodeid(m_handle, m_version, m_node_type); if(res >= 0) return _ownNodeId= (Uint32)res; From d2ac9b5b6788f65eeb0b8ae38ad71c7ea7805a03 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 16:11:59 +0200 Subject: [PATCH 09/29] table t7 was not dropped at the end mysql-test/r/join_nested.result: drop t7 mysql-test/t/join_nested.test: drop t7 --- mysql-test/r/join_nested.result | 2 +- mysql-test/t/join_nested.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index c4dd6cf9a86..b3ba5423421 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -1466,4 +1466,4 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ref a a 5 test.t3.b X 1 SIMPLE t6 ref a a 5 test.t4.b X 1 SIMPLE t5 ref a a 5 test.t3.b X -drop table t0, t1, t2, t4, t5, t6; +drop table t0, t1, t2, t4, t5, t6, t7; diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index 9dbf153ec55..6e4e64bda9c 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -899,4 +899,4 @@ explain select * from t2 left join (t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b join t5 on t5.a=t3.b) on t3.a=t2.b; -drop table t0, t1, t2, t4, t5, t6; +drop table t0, t1, t2, t4, t5, t6, t7; From 102c0281fa1a746d6d473fbb22237a5dac1b82ba Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 16:21:07 +0100 Subject: [PATCH 10/29] Moved check of wrong schema version earlier --- sql/ha_ndbcluster.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 6760208488f..e06559dc593 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3285,12 +3285,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion())); } - if (m_table != (void *)tab) - { - m_table= (void *)tab; - m_table_version = tab->getObjectVersion(); - } - else if (m_table_version < tab->getObjectVersion()) + if (m_table_version < tab->getObjectVersion()) { /* The table has been altered, caller has to retry @@ -3298,6 +3293,13 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT); DBUG_RETURN(ndb_to_mysql_error(&err)); } + if (m_table != (void *)tab) + { + m_table= (void *)tab; + m_table_version = tab->getObjectVersion(); + if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN))) + DBUG_RETURN(my_errno); + } m_table_info= tab_info; } no_uncommitted_rows_init(thd); From 54f9b2cc1b5dfaf5f465852a02ef7289a1ac2e7a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 18:27:14 +0300 Subject: [PATCH 11/29] Polishing: get rid of C++-style comments. mysys/my_open.c: Get rid of C++-style comments. --- mysys/my_open.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysys/my_open.c b/mysys/my_open.c index baca97450b7..6ed3cb5becf 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -267,7 +267,7 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode) */ switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) { case 0: - case _O_EXCL: // ignore EXCL w/o CREAT + case _O_EXCL: /* ignore EXCL w/o CREAT */ filecreate= OPEN_EXISTING; break; @@ -281,7 +281,7 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode) break; case _O_TRUNC: - case _O_TRUNC | _O_EXCL: // ignore EXCL w/o CREAT + case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */ filecreate= TRUNCATE_EXISTING; break; @@ -290,7 +290,7 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode) break; default: - // this can't happen ... all cases are covered + /* this can't happen ... all cases are covered */ errno= EINVAL; _doserrno= 0L; return -1; From e6d90f51de36fe91aa21746403200d3392306d57 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 18:42:39 +0300 Subject: [PATCH 12/29] Make it buildable with -ansi flag on some platforms. extra/innochecksum.c: Define _XOPEN_SOURCE in order to include getopt.h when needed. The problem is that some platforms (for instance, SuSE 9.1/gcc-3.3.3) do not include getopt.h unless _XOPEN_SOURCE is defined, so optarg is undefined and the compiler complains. --- extra/innochecksum.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extra/innochecksum.c b/extra/innochecksum.c index 739953298af..bae5f3e8821 100644 --- a/extra/innochecksum.c +++ b/extra/innochecksum.c @@ -28,6 +28,8 @@ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE +#define _XOPEN_SOURCE /* needed to include getopt.h on some platforms. */ + #include #include #include From 3190b21f95e58886e1507384bf792ed68a9f8397 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 19:16:51 +0300 Subject: [PATCH 13/29] Fix bug #14482 Wrongly applied optimization in resolve_const_item() caused crash resolve_const_item() substitutes item which will evaluate to constant with equvalent constant item, basing on the item's result type. In this case subselect was resolved as constant, and resolve_const_item() was substituting it's result's Item_caches to Item_null. Later Item_cache's function was called for Item_null object, which caused server crash. resolve_const_item() now substitutes constants for items with result_type == ROW_RESULT only for Item_rows. sql/item.cc: Fix bug #14482 Wrongly applied optimization in resolve_const_item() caused crash resolve_const_item() now applies optimization for items with result_type == ROW_RESULT only to Item_rows. mysql-test/t/select.test: Test case for bug #14482 Wrongly applied optimization in resolve_const_item() caused crash mysql-test/r/select.result: Test case for bug #14482 Wrongly applied optimization in resolve_const_item() caused crash --- mysql-test/r/select.result | 8 ++++++++ mysql-test/t/select.test | 11 +++++++++++ sql/item.cc | 15 ++++++++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 64c329ee104..b80ca2b195e 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2706,3 +2706,11 @@ select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; count(f2) >0 1 drop table t1,t2; +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +f1 f2 +1 1 +drop table t1,t2; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 39c7cdfa8a9..996d5854854 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2237,4 +2237,15 @@ insert into t1 values (1,1); insert into t2 values (1,1),(1,2); select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; drop table t1,t2; + +# +# Bug #14482 Server crash when subselecting from the same table +# +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +drop table t1,t2; + # End of 4.1 tests diff --git a/sql/item.cc b/sql/item.cc index 642a0ccf1b4..6ca2627dbff 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2863,7 +2863,7 @@ Item_result item_cmp_type(Item_result a,Item_result b) void resolve_const_item(THD *thd, Item **ref, Item *comp_item) { Item *item= *ref; - Item *new_item; + Item *new_item= NULL; if (item->basic_const_item()) return; // Can't be better Item_result res_type=item_cmp_type(comp_item->result_type(), @@ -2892,8 +2892,17 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) new_item= (null_value ? (Item*) new Item_null(name) : (Item*) new Item_int(name, result, length)); } - else if (res_type == ROW_RESULT) + else if (res_type == ROW_RESULT && item->type() == Item::ROW_ITEM && + comp_item->type() == Item::ROW_ITEM) { + /* + Substitute constants only in Item_rows. Don't affect other Items + with ROW_RESULT (eg Item_singlerow_subselect). + + For such Items more optimal is to detect if it is constant and replace + it with Item_row. This would optimize queries like this: + SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1); + */ Item_row *item_row= (Item_row*) item; Item_row *comp_item_row= (Item_row*) comp_item; uint col; @@ -2910,7 +2919,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) while (col-- > 0) resolve_const_item(thd, item_row->addr(col), comp_item_row->el(col)); } - else + else if (res_type == REAL_RESULT) { // It must REAL_RESULT double result=item->val(); uint length=item->max_length,decimals=item->decimals; From a101950d7b2adf1c08de95e581b4d1d5bd84e361 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 17:17:36 +0100 Subject: [PATCH 14/29] Bug #15168 yassl failure on amd64 - Use libtool to build libraries config/ac-macros/yassl.m4: If necessary, disable inlining for all files in libtaocrypt not only integer.cpp Remove ver yassl_libs_with_path, not used anymore extra/yassl/src/Makefile.am: Let libtool build libraries extra/yassl/taocrypt/src/Makefile.am: Let libtool build libraries Only build one lib libmysqld/Makefile.am: Dont include yassl libs in libmysqld libmysqld/examples/Makefile.am: Add yassl includes and libs when linking examples with libmysqld --- config/ac-macros/yassl.m4 | 10 ++++------ extra/yassl/src/Makefile.am | 4 ++-- extra/yassl/taocrypt/src/Makefile.am | 12 ++++-------- libmysqld/Makefile.am | 3 +-- libmysqld/examples/Makefile.am | 4 ++-- 5 files changed, 13 insertions(+), 20 deletions(-) diff --git a/config/ac-macros/yassl.m4 b/config/ac-macros/yassl.m4 index 9d9a4d55000..d1216554862 100644 --- a/config/ac-macros/yassl.m4 +++ b/config/ac-macros/yassl.m4 @@ -16,7 +16,6 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [ AC_MSG_RESULT([using bundled yaSSL]) yassl_dir="extra/yassl" yassl_libs="-L\$(top_srcdir)/extra/yassl/src -lyassl -L\$(top_srcdir)/extra/yassl/taocrypt/src -ltaocrypt" - yassl_libs_with_path="\$(top_srcdir)/extra/yassl/src/libyassl.a \$(top_srcdir)/extra/yassl/taocrypt/src/libtaocrypt.a" yassl_includes="-I\$(top_srcdir)/extra/yassl/include" AC_DEFINE([HAVE_OPENSSL], [1], [Defined by configure. Using yaSSL for OpenSSL emulation.]) AC_DEFINE([HAVE_YASSL], [1], [Defined by configure. Using yaSSL for OpenSSL emulation.]) @@ -24,12 +23,12 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [ yassl_integer_extra_cxxflags="" case $host_cpu--$CXX_VERSION in sparc*--*Sun*C++*5.6*) - # Disable inlining when compiling taocrypt/src/integer.cpp - yassl_integer_extra_cxxflags="+d" - AC_MSG_NOTICE([disabling inlining for yassl/taocrypt/src/integer.cpp]) + # Disable inlining when compiling taocrypt/src/ + yassl_taocrypt_extra_cxxflags="+d" + AC_MSG_NOTICE([disabling inlining for yassl/taocrypt/src/]) ;; esac - AC_SUBST([yassl_integer_extra_cxxflags]) + AC_SUBST([yassl_taocrypt_extra_cxxflags]) else yassl_dir="" @@ -38,6 +37,5 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [ AC_SUBST(yassl_libs) AC_SUBST(yassl_includes) AC_SUBST(yassl_dir) - AC_SUBST(yassl_libs_with_path) AM_CONDITIONAL([HAVE_YASSL], [ test "with_yassl" = "yes" ]) ]) diff --git a/extra/yassl/src/Makefile.am b/extra/yassl/src/Makefile.am index df96018e1cf..a852ca4019b 100644 --- a/extra/yassl/src/Makefile.am +++ b/extra/yassl/src/Makefile.am @@ -1,7 +1,7 @@ INCLUDES = -I../include -I../taocrypt/include -I../mySTL -noinst_LIBRARIES = libyassl.a -libyassl_a_SOURCES = buffer.cpp cert_wrapper.cpp crypto_wrapper.cpp \ +noinst_LTLIBRARIES = libyassl.la +libyassl_la_SOURCES = buffer.cpp cert_wrapper.cpp crypto_wrapper.cpp \ handshake.cpp lock.cpp log.cpp socket_wrapper.cpp ssl.cpp \ template_instnt.cpp timer.cpp yassl_imp.cpp yassl_error.cpp yassl_int.cpp EXTRA_DIST = $(wildcard ../include/*.hpp) $(wildcard ../include/openssl/*.h) diff --git a/extra/yassl/taocrypt/src/Makefile.am b/extra/yassl/taocrypt/src/Makefile.am index 0319fc6057b..d89fa95a940 100644 --- a/extra/yassl/taocrypt/src/Makefile.am +++ b/extra/yassl/taocrypt/src/Makefile.am @@ -1,15 +1,11 @@ INCLUDES = -I../include -I../../mySTL -noinst_LIBRARIES = libtaoint.a libtaocrypt.a +noinst_LTLIBRARIES = libtaocrypt.la -libtaoint_a_SOURCES = integer.cpp -libtaoint_a_CXXFLAGS = @yassl_integer_extra_cxxflags@ - -libtaocrypt_a_SOURCES = aes.cpp aestables.cpp algebra.cpp arc4.cpp asn.cpp \ +libtaocrypt_la_SOURCES = aes.cpp aestables.cpp algebra.cpp arc4.cpp asn.cpp \ coding.cpp dh.cpp des.cpp dsa.cpp file.cpp hash.cpp \ md2.cpp md5.cpp misc.cpp random.cpp ripemd.cpp rsa.cpp sha.cpp \ - template_instnt.cpp -libtaocrypt_a_LIBADD = libtaoint_a-integer.o + template_instnt.cpp integer.cpp +libtaocrypt_la_CXXFLAGS = @yassl_taocrypt_extra_cxxflags@ -DYASSL_PURE_C EXTRA_DIST = $(wildcard ../include/*.hpp) -AM_CXXFLAGS = -DYASSL_PURE_C diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 8ddc8752f07..f07bbacba02 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -80,8 +80,7 @@ INC_LIB= $(top_builddir)/regex/libregex.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a \ $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/vio/libvio.a \ - @yassl_libs_with_path@ + $(top_builddir)/vio/libvio.a # diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index 925a6573efe..414cf63b003 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -34,8 +34,8 @@ link_sources: DEFS = -DEMBEDDED_LIBRARY INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir) \ -I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \ - $(openssl_includes) -LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ + $(openssl_includes) $(yassl_includes) +LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs) LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) mysqltest_embedded_LINK = $(CXXLINK) From 591fabb390e2fbf7f54e7d54ccce38065e8b4507 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 19:54:02 +0300 Subject: [PATCH 15/29] Fix bug#13293 Wrongly used index results in endless loop. Loose index scan using only second part of multipart index was choosen, which results in creating wrong keys and endless loop. get_best_group_min_max() now allows loose index scan for distinct only if used keyparts forms a prefix of the index. mysql-test/t/group_min_max.test: Test case for bug #13293 Wrongly used index results in endless loop. mysql-test/r/group_min_max.result: Test case for bug #13293 Wrongly used index results in endless loop. sql/opt_range.cc: Fix bug #13293 Wrongly used index results in endless loop. get_best_group_min_max() now allows loose index scan for distinct only if used keyparts forms a prefix of the index. --- mysql-test/r/group_min_max.result | 10 ++++++++++ mysql-test/t/group_min_max.test | 10 ++++++++++ sql/opt_range.cc | 13 +++++++++++++ 3 files changed, 33 insertions(+) diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 038d0c75f74..91f7eaeea2c 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2002,3 +2002,13 @@ a count(a) 1 1 NULL 1 drop table t1; +create table t1 (f1 int, f2 char(1), primary key(f1,f2)) engine=innodb; +insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d"); +alter table t1 drop primary key, add primary key (f2, f1); +explain select distinct f1 a, f1 b from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary +explain select distinct f1, f2 from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary +drop table t1; diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 3d751f4a571..9738bbcca49 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -693,3 +693,13 @@ create table t1(a int, key(a)) engine=innodb; insert into t1 values(1); select a, count(a) from t1 group by a with rollup; drop table t1; + +# +# Bug #13293 Wrongly used index results in endless loop. +# +create table t1 (f1 int, f2 char(1), primary key(f1,f2)) engine=innodb; +insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d"); +alter table t1 drop primary key, add primary key (f2, f1); +explain select distinct f1 a, f1 b from t1; +explain select distinct f1, f2 from t1; +drop table t1; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 323e829f219..cddcec29ecc 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7197,6 +7197,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) { select_items_it.rewind(); cur_used_key_parts.clear_all(); + uint max_key_part= 0; while ((item= select_items_it++)) { item_field= (Item_field*) item; /* (SA5) already checked above. */ @@ -7214,7 +7215,19 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) cur_group_prefix_len+= cur_part->store_length; cur_used_key_parts.set_bit(key_part_nr); ++cur_group_key_parts; + max_key_part= max(max_key_part,key_part_nr); } + /* + Check that used key parts forms a prefix of the index. + To check this we compare bits in all_parts and cur_parts. + all_parts have all bits set from 0 to (max_key_part-1). + cur_parts have bits set for only used keyparts. + */ + ulonglong all_parts, cur_parts; + all_parts= (1<> 1; + if (all_parts != cur_parts) + goto next_index; } else DBUG_ASSERT(FALSE); From f8aae3e6049d1e2f1109b75cf56f415aa1dd2509 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 18:13:08 +0100 Subject: [PATCH 16/29] don't call handler::info() in SHOW CREATE TABLE --- sql/sql_show.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 9449224c01a..cb537a43053 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -898,7 +898,6 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) } key_info= table->key_info; - file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); bzero((char*) &create_info, sizeof(create_info)); file->update_create_info(&create_info); primary_key= share->primary_key; From 0b262a6213a85ce3512facb23950145d051dca46 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 19:13:13 +0100 Subject: [PATCH 17/29] Some post-merge cleaning, and made assert THD::store_globals() work at all times. mysql-test/t/sp.test: Tidying up after merge. sql/mysqld.cc: Make sure we have thd->thread_stack set before calling store_globals(). (And fixed compiler warning.) sql/sql_class.cc: Init THD::tread_stack in constructor. --- mysql-test/t/sp.test | 2 ++ sql/mysqld.cc | 5 ++++- sql/sql_class.cc | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 56b64532ab8..fba3cfcbfbc 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -4773,6 +4773,8 @@ drop procedure bug10100pv| drop procedure bug10100pd| drop procedure bug10100pc| drop view v1| + +# # BUG#13729: Stored procedures: packet error after exception handled # --disable_warnings diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b5b95e48889..8792d2560ae 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1589,6 +1589,7 @@ void end_thread(THD *thd, bool put_in_cache) wake_thread--; thd=thread_cache.get(); thd->real_id=pthread_self(); + thd->thread_stack= (char *) &thd; (void) thd->store_globals(); thd->thr_create_time= time(NULL); threads.append(thd); @@ -6912,8 +6913,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case OPT_MYISAM_STATS_METHOD: { ulong method_conv; - myisam_stats_method_str= argument; int method; + LINT_INIT(method_conv); + + myisam_stats_method_str= argument; if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0) { fprintf(stderr, "Invalid value of myisam_stats_method: %s.\n", argument); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b65f353e492..70dfaca53d3 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -183,6 +183,7 @@ THD::THD() spcont(NULL) { stmt_arena= this; + thread_stack= 0; db= 0; catalog= (char*)"std"; // the only catalog we have for now main_security_ctx.init(); From dc8a5d54bd82659d81649176ece97878ba151214 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 Nov 2005 19:51:52 +0100 Subject: [PATCH 18/29] Remove t3 in join_nested.test mysql-test/r/join_nested.result: Remove t3 too. mysql-test/t/join_nested.test: Remove t3 too. --- mysql-test/r/join_nested.result | 2 +- mysql-test/t/join_nested.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index b3ba5423421..6b7293d46bc 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -1466,4 +1466,4 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ref a a 5 test.t3.b X 1 SIMPLE t6 ref a a 5 test.t4.b X 1 SIMPLE t5 ref a a 5 test.t3.b X -drop table t0, t1, t2, t4, t5, t6, t7; +drop table t0, t1, t2, t3, t4, t5, t6, t7; diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index 6e4e64bda9c..9f23e2d0e2f 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -899,4 +899,4 @@ explain select * from t2 left join (t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b join t5 on t5.a=t3.b) on t3.a=t2.b; -drop table t0, t1, t2, t4, t5, t6, t7; +drop table t0, t1, t2, t3, t4, t5, t6, t7; From e1af5e5dfd302b03b12e897812ecbb7befb98c3d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Nov 2005 10:41:22 +0100 Subject: [PATCH 19/29] Updated expected error --- mysql-test/r/ndb_alter_table.result | 2 +- mysql-test/t/ndb_alter_table.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result index 62e8455ae9f..b5fceba7cee 100644 --- a/mysql-test/r/ndb_alter_table.result +++ b/mysql-test/r/ndb_alter_table.result @@ -179,7 +179,7 @@ a b c 2 two two alter table t1 drop index c; select * from t1 where b = 'two'; -ERROR HY000: Table definition has changed, please retry transaction +ERROR HY000: Can't lock file (errno: 241) select * from t1 where b = 'two'; a b c 2 two two diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test index d89b81859e7..22383a82bca 100644 --- a/mysql-test/t/ndb_alter_table.test +++ b/mysql-test/t/ndb_alter_table.test @@ -149,7 +149,7 @@ connection server1; alter table t1 drop index c; connection server2; # This should fail since index information is not automatically refreshed ---error 1105 +--error 1015 select * from t1 where b = 'two'; select * from t1 where b = 'two'; connection server1; From 2a1ae3a5e3cbc7bb076c91ba0f8b5e6242319b28 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Nov 2005 13:25:31 +0300 Subject: [PATCH 20/29] A fix and a test case for Bug#14410 "Crash in Enum or Set type in CREATE TABLE and PS/SP": make sure that 'typelib' object for ENUM values and 'Item_string' object for DEFAULT clause are created in the statement memory root. mysql-test/r/ps.result: Test results has been fixed (Bug#14410) mysql-test/t/ps.test: A test case for Bug#14410 "Crash in Enum or Set type in CREATE TABLE and PS/SP" sql/mysql_priv.h: typelib() function declaration has been changed. sql/sql_table.cc: Supply the statement memory root to use in typelib() and safe_charset_converter() functions to ensure that objects created during the first execution of CREATE TABLE statement are allocated in persistent memory of the statement. sql/table.cc: Change typelib() function to require MEM_ROOT. --- mysql-test/r/ps.result | 19 +++++++++++++++++++ mysql-test/t/ps.test | 29 +++++++++++++++++++++++++++++ sql/mysql_priv.h | 2 +- sql/sql_table.cc | 29 +++++++++++++++++++++++++---- sql/table.cc | 6 +++--- 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f5bf3ffa96d..d46c2d5b3d5 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -699,3 +699,22 @@ execute stmt; @@tx_isolation REPEATABLE-READ deallocate prepare stmt; +prepare stmt from "create temporary table t1 (letter enum('','a','b','c') +not null)"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +set names latin1; +prepare stmt from "create table t1 (a enum('test') default 'test') + character set utf8"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +set names default; +deallocate prepare stmt; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index c4cb0056763..82dfc643801 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -718,4 +718,33 @@ set @@tx_isolation=default; execute stmt; deallocate prepare stmt; +# +# Bug#14410 "Crash in Enum or Set type in CREATE TABLE and PS/SP" +# +# Part I. Make sure the typelib for ENUM is created in the statement memory +# root. +prepare stmt from "create temporary table t1 (letter enum('','a','b','c') +not null)"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +# Part II. Make sure that when the default value is converted to UTF-8, +# the new item is # created in the statement memory root. +set names latin1; +prepare stmt from "create table t1 (a enum('test') default 'test') + character set utf8"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +# Cleanup +set names default; +deallocate prepare stmt; + # End of 4.1 tests + diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a9057ae24f6..c128fac8d9e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1119,7 +1119,7 @@ int calc_weekday(long daynr,bool sunday_first_day_of_week); 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); +TYPELIB *typelib(MEM_ROOT *mem_root, List &strings); ulong get_form_pos(File file, uchar *head, TYPELIB *save_names); ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames, const char *newname); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0e0a05ea099..294c59af90f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -524,7 +524,14 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (!interval) { - interval= sql_field->interval= typelib(sql_field->interval_list); + /* + Create the typelib in prepared statement memory if we're + executing one. + */ + MEM_ROOT *stmt_root= thd->current_arena->mem_root; + + interval= sql_field->interval= typelib(stmt_root, + sql_field->interval_list); List_iterator it(sql_field->interval_list); String conv, *tmp; for (uint i= 0; (tmp= it++); i++) @@ -534,7 +541,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { uint cnv_errs; conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs); - char *buf= (char*) sql_alloc(conv.length()+1); + char *buf= (char*) alloc_root(stmt_root, conv.length()+1); memcpy(buf, conv.ptr(), conv.length()); buf[conv.length()]= '\0'; interval->type_names[i]= buf; @@ -556,8 +563,22 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (sql_field->def && cs != sql_field->def->collation.collation) { - if (!(sql_field->def= - sql_field->def->safe_charset_converter(cs))) + Item_arena backup_arena; + bool need_to_change_arena= + !thd->current_arena->is_conventional_execution(); + if (need_to_change_arena) + { + /* Asser that we don't do that at every PS execute */ + DBUG_ASSERT(thd->current_arena->is_first_stmt_execute()); + thd->set_n_backup_item_arena(thd->current_arena, &backup_arena); + } + + sql_field->def= sql_field->def->safe_charset_converter(cs); + + if (need_to_change_arena) + thd->restore_backup_item_arena(thd->current_arena, &backup_arena); + + if (! sql_field->def) { /* Could not convert */ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); diff --git a/sql/table.cc b/sql/table.cc index 04d1a95cd9b..de539205ffd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1099,15 +1099,15 @@ fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types, } /* fix_type_pointers */ -TYPELIB *typelib(List &strings) +TYPELIB *typelib(MEM_ROOT *mem_root, List &strings) { - TYPELIB *result=(TYPELIB*) sql_alloc(sizeof(TYPELIB)); + TYPELIB *result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB)); if (!result) return 0; result->count=strings.elements; result->name=""; uint nbytes= (sizeof(char*) + sizeof(uint)) * (result->count + 1); - if (!(result->type_names= (const char**) sql_alloc(nbytes))) + if (!(result->type_names= (const char**) alloc_root(mem_root, nbytes))) return 0; result->type_lengths= (uint*) (result->type_names + result->count + 1); List_iterator it(strings); From 2e79201c727a593d93eae269e48e0240161525fd Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Nov 2005 18:53:55 +0300 Subject: [PATCH 21/29] Post-merge fixes. --- mysql-test/r/ndb_basic.result | 8 ++++---- mysql-test/r/ps.result | 19 +++++++++++++++++++ mysql-test/r/select.result | 8 ++++++++ sql/sql_table.cc | 15 +++++++-------- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index e288592c390..55cbbd89b3c 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -667,13 +667,13 @@ counter datavalue 57 newval 58 newval drop table t1; +CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; +select * from t1; +b +drop table t1; create table atablewithareallylongandirritatingname (a int); insert into atablewithareallylongandirritatingname values (2); select * from atablewithareallylongandirritatingname; a 2 drop table atablewithareallylongandirritatingname; -CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb; -select * from t1; -b -drop table t1; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f1c3672083d..742f68be445 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -806,3 +806,22 @@ execute stmt; @@tx_isolation REPEATABLE-READ deallocate prepare stmt; +prepare stmt from "create temporary table t1 (letter enum('','a','b','c') +not null)"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +set names latin1; +prepare stmt from "create table t1 (a enum('test') default 'test') + character set utf8"; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +execute stmt; +drop table t1; +set names default; +deallocate prepare stmt; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 8a126b7ddfb..e9348a6640f 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2708,6 +2708,14 @@ select distinct count(f2) >0 from t1 left join t2 on f1=f3 group by f1; count(f2) >0 1 drop table t1,t2; +create table t1 (f1 int,f2 int); +insert into t1 values(1,1); +create table t2 (f3 int, f4 int, primary key(f3,f4)); +insert into t2 values(1,1); +select * from t1 where f1 in (select f3 from t2 where (f3,f4)= (select f3,f4 from t2)); +f1 f2 +1 1 +drop table t1,t2; CREATE TABLE t1 ( city char(30) ); INSERT INTO t1 VALUES ('London'); INSERT INTO t1 VALUES ('Paris'); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 03ed0fe4e66..949417dfa30 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -729,7 +729,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, Create the typelib in prepared statement memory if we're executing one. */ - MEM_ROOT *stmt_root= thd->current_arena->mem_root; + MEM_ROOT *stmt_root= thd->stmt_arena->mem_root; interval= sql_field->interval= typelib(stmt_root, sql_field->interval_list); @@ -763,21 +763,20 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (sql_field->def && cs != sql_field->def->collation.collation) { - Item_arena backup_arena; - bool need_to_change_arena= - !thd->current_arena->is_conventional_execution(); + Query_arena backup_arena; + bool need_to_change_arena= !thd->stmt_arena->is_conventional(); if (need_to_change_arena) { /* Asser that we don't do that at every PS execute */ - DBUG_ASSERT(thd->current_arena->is_first_stmt_execute() || - thd->current_arena->is_first_sp_execute()); - thd->set_n_backup_item_arena(thd->current_arena, &backup_arena); + DBUG_ASSERT(thd->stmt_arena->is_first_stmt_execute() || + thd->stmt_arena->is_first_sp_execute()); + thd->set_n_backup_active_arena(thd->stmt_arena, &backup_arena); } sql_field->def= sql_field->def->safe_charset_converter(cs); if (need_to_change_arena) - thd->restore_backup_item_arena(thd->current_arena, &backup_arena); + thd->restore_active_arena(thd->stmt_arena, &backup_arena); if (! sql_field->def) { From 08a4868bb66235db4d0011a26082067d1e368e92 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Nov 2005 20:47:22 +0300 Subject: [PATCH 22/29] BUG#15024: get_best_covering_ror_intersect() tries to build ROR-intersection by starting with an empty index set and adding indexes to it until it becomes covering. If the set becomes covering after adding the first index, return NULL and don't try constructing ROR-intersection of one index (which caused a crash) --- sql/opt_range.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 323e829f219..bf7eb370e42 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3136,10 +3136,10 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, /* F=F-covered by first(I) */ bitmap_union(&covered_fields, &(*ror_scan_mark)->covered_fields); all_covered= bitmap_is_subset(¶m->needed_fields, &covered_fields); - } while (!all_covered && (++ror_scan_mark < ror_scans_end)); - - if (!all_covered) - DBUG_RETURN(NULL); /* should not happen actually */ + } while ((++ror_scan_mark < ror_scans_end) && !all_covered); + + if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1) + DBUG_RETURN(NULL); /* Ok, [tree->ror_scans .. ror_scan) holds covering index_intersection with From fd4fcd2f7ff58591f3e43a82d3d1dc50758bc8ab Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Nov 2005 18:51:44 -0800 Subject: [PATCH 23/29] Fixed bug #15106. A typo bug caused loss of a predicate of the form field=const in some cases. mysql-test/r/select.result: Added a test case for bug #15106. mysql-test/t/select.test: Added a test case for bug #15106. --- mysql-test/r/select.result | 46 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/select.test | 45 +++++++++++++++++++++++++++++++++++++ sql/item_cmpfunc.cc | 2 +- 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index e9348a6640f..598ea2b10d1 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3291,3 +3291,49 @@ f1 f2 x1 30 1 30 drop table t1; drop view v1, v2, v3; +CREATE TABLE t1(key_a int4 NOT NULL, optimus varchar(32), PRIMARY KEY(key_a)); +CREATE TABLE t2(key_a int4 NOT NULL, prime varchar(32), PRIMARY KEY(key_a)); +CREATE table t3(key_a int4 NOT NULL, key_b int4 NOT NULL, foo varchar(32), +PRIMARY KEY(key_a,key_b)); +INSERT INTO t1 VALUES (0,''); +INSERT INTO t1 VALUES (1,'i'); +INSERT INTO t1 VALUES (2,'j'); +INSERT INTO t1 VALUES (3,'k'); +INSERT INTO t2 VALUES (1,'r'); +INSERT INTO t2 VALUES (2,'s'); +INSERT INTO t2 VALUES (3,'t'); +INSERT INTO t3 VALUES (1,5,'x'); +INSERT INTO t3 VALUES (1,6,'y'); +INSERT INTO t3 VALUES (2,5,'xx'); +INSERT INTO t3 VALUES (2,6,'yy'); +INSERT INTO t3 VALUES (2,7,'zz'); +INSERT INTO t3 VALUES (3,5,'xxx'); +SELECT t2.key_a,foo +FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a +INNER JOIN t3 ON t1.key_a = t3.key_a +WHERE t2.key_a=2 and key_b=5; +key_a foo +2 xx +EXPLAIN SELECT t2.key_a,foo +FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a +INNER JOIN t3 ON t1.key_a = t3.key_a +WHERE t2.key_a=2 and key_b=5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1 +SELECT t2.key_a,foo +FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a +INNER JOIN t3 ON t1.key_a = t3.key_a +WHERE t2.key_a=2 and key_b=5; +key_a foo +2 xx +EXPLAIN SELECT t2.key_a,foo +FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a +INNER JOIN t3 ON t1.key_a = t3.key_a +WHERE t2.key_a=2 and key_b=5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t3 const PRIMARY PRIMARY 8 const,const 1 +DROP TABLE t1,t2,t3; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 4eaa8eca052..a73d08f5f18 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2760,3 +2760,48 @@ select f1, f2, v2.f1 as x1 from v2 order by v2.f1; select f1, f2, v3.f1 as x1 from v3 order by v3.f1; drop table t1; drop view v1, v2, v3; + +# +# Bug #15106: lost equality predicate of the form field=const in a join query +# + +CREATE TABLE t1(key_a int4 NOT NULL, optimus varchar(32), PRIMARY KEY(key_a)); +CREATE TABLE t2(key_a int4 NOT NULL, prime varchar(32), PRIMARY KEY(key_a)); +CREATE table t3(key_a int4 NOT NULL, key_b int4 NOT NULL, foo varchar(32), + PRIMARY KEY(key_a,key_b)); + +INSERT INTO t1 VALUES (0,''); +INSERT INTO t1 VALUES (1,'i'); +INSERT INTO t1 VALUES (2,'j'); +INSERT INTO t1 VALUES (3,'k'); + +INSERT INTO t2 VALUES (1,'r'); +INSERT INTO t2 VALUES (2,'s'); +INSERT INTO t2 VALUES (3,'t'); + +INSERT INTO t3 VALUES (1,5,'x'); +INSERT INTO t3 VALUES (1,6,'y'); +INSERT INTO t3 VALUES (2,5,'xx'); +INSERT INTO t3 VALUES (2,6,'yy'); +INSERT INTO t3 VALUES (2,7,'zz'); +INSERT INTO t3 VALUES (3,5,'xxx'); + +SELECT t2.key_a,foo + FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a + INNER JOIN t3 ON t1.key_a = t3.key_a + WHERE t2.key_a=2 and key_b=5; +EXPLAIN SELECT t2.key_a,foo + FROM t1 INNER JOIN t2 ON t1.key_a = t2.key_a + INNER JOIN t3 ON t1.key_a = t3.key_a + WHERE t2.key_a=2 and key_b=5; + +SELECT t2.key_a,foo + FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a + INNER JOIN t3 ON t1.key_a = t3.key_a + WHERE t2.key_a=2 and key_b=5; +EXPLAIN SELECT t2.key_a,foo + FROM t1 INNER JOIN t2 ON t2.key_a = t1.key_a + INNER JOIN t3 ON t1.key_a = t3.key_a + WHERE t2.key_a=2 and key_b=5; + +DROP TABLE t1,t2,t3; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2a7754c0217..ae8437674b2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -3662,7 +3662,7 @@ void Item_equal::merge(Item_equal *item) the multiple equality already contains a constant and its value is not equal to the value of c. */ - add(const_item); + add(c); } cond_false|= item->cond_false; } From 94ab2caa6d1596c2be3a5d249622207f4d00579c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 26 Nov 2005 08:54:13 +0100 Subject: [PATCH 24/29] documenting HA_STATUS_xxx flags --- include/my_base.h | 49 +++++++++++++++++++++++++++++++------- sql/examples/ha_example.cc | 2 ++ sql/handler.h | 2 +- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index ba3edfad0c8..a2d43304adf 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -260,15 +260,48 @@ enum ha_base_keytype { #define HA_CREATE_CHECKSUM 8 #define HA_CREATE_DELAY_KEY_WRITE 64 - /* Bits in flag to _status */ +/* + The following flags (OR-ed) are passed to handler::info() method. + The method copies misc handler information out of the storage engine + to data structures accessible from MySQL -#define HA_STATUS_POS 1 /* Return position */ -#define HA_STATUS_NO_LOCK 2 /* Don't use external lock */ -#define HA_STATUS_TIME 4 /* Return update time */ -#define HA_STATUS_CONST 8 /* Return constants values */ -#define HA_STATUS_VARIABLE 16 -#define HA_STATUS_ERRKEY 32 -#define HA_STATUS_AUTO 64 + Same flags are also passed down to mi_status, myrg_status, etc. +*/ + +/* this one is not used */ +#define HA_STATUS_POS 1 +/* + assuming the table keeps shared actual copy of the 'info' and + local, possibly outdated copy, the following flag means that + it should not try to get the actual data (locking the shared structure) + slightly outdated version will suffice +*/ +#define HA_STATUS_NO_LOCK 2 +/* update the time of the last modification (in handler::update_time) */ +#define HA_STATUS_TIME 4 +/* + update the 'constant' part of the info: + handler::max_data_file_length, max_index_file_length, create_time + sortkey, ref_length, block_size, data_file_name, index_file_name. + handler::table->s->keys_in_use, keys_for_keyread, rec_per_key +*/ +#define HA_STATUS_CONST 8 +/* + update the 'variable' part of the info: + handler::records, deleted, data_file_length, index_file_length, + delete_length, check_time, mean_rec_length +*/ +#define HA_STATUS_VARIABLE 16 +/* + get the information about the key that caused last duplicate value error + update handler::errkey and handler::dupp_ref + see handler::get_dup_key() +*/ +#define HA_STATUS_ERRKEY 32 +/* + update handler::auto_increment_value +*/ +#define HA_STATUS_AUTO 64 /* Errorcodes given by functions */ diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc index d340b9289ec..471ece77490 100644 --- a/sql/examples/ha_example.cc +++ b/sql/examples/ha_example.cc @@ -480,6 +480,8 @@ int ha_example::rnd_pos(byte * buf, byte *pos) /* ::info() is used to return information to the optimizer. + see my_base.h for the complete description + Currently this table handler doesn't implement most of the fields really needed. SHOW also makes use of this data Another note, you will probably want to have the following in your diff --git a/sql/handler.h b/sql/handler.h index be188f7cacd..91c5be9ba39 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -672,7 +672,7 @@ public: key_range *max_key) { return (ha_rows) 10; } virtual void position(const byte *record)=0; - virtual void info(uint)=0; + virtual void info(uint)=0; // see my_base.h for full description virtual int extra(enum ha_extra_function operation) { return 0; } virtual int extra_opt(enum ha_extra_function operation, ulong cache_size) From 06887bc3304b4e6323ca8aa4c1d73d32b3f960c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 26 Nov 2005 19:15:17 +0300 Subject: [PATCH 25/29] Enabled back bunch of tests for stored routines which were disabled earlier because of various features/checks missing (these features/checks are now implemented). mysql-test/r/sp.result: Enabled back bunch of tests which were previously disabled because of various features/checks missing (since these features/checks are now implemented). mysql-test/t/sp.test: Enabled back bunch of tests which were previously disabled because of various features/checks missing (since these features/checks are now implemented). --- mysql-test/r/sp.result | 126 ++++++++++++++++++++++++++++++++++++++++- mysql-test/t/sp.test | 65 ++++++++------------- 2 files changed, 148 insertions(+), 43 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 231ca329f3d..bb09bf62f40 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -988,6 +988,10 @@ end| select f5(1)| f5(1) 1 +select f5(2)| +ERROR HY000: Recursive stored functions and triggers are not allowed. +select f5(3)| +ERROR HY000: Recursive stored functions and triggers are not allowed. create function f6() returns int begin declare n int; @@ -1035,6 +1039,12 @@ select * from v1| ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them create function f1() returns int return (select sum(data) from t1) + (select sum(data) from v1)| +select f1()| +ERROR HY000: Recursive stored functions and triggers are not allowed. +select * from v1| +ERROR HY000: Recursive stored functions and triggers are not allowed. +select * from v2| +ERROR HY000: Recursive stored functions and triggers are not allowed. drop function f1| create function f1() returns int return (select sum(data) from t1)| @@ -1053,7 +1063,7 @@ f0() select *, f0() from v0| f0() f0() 100 100 -lock tables t1 read, t1 as t11 read, mysql.proc read| +lock tables t1 read, t1 as t11 read| select f3()| f3() 1 @@ -1251,6 +1261,62 @@ drop procedure opp| drop procedure ip| show procedure status like '%p%'| Db Name Type Definer Modified Created Security_type Comment +drop table if exists fib| +create table fib ( f bigint unsigned not null )| +drop procedure if exists fib| +create procedure fib(n int unsigned) +begin +if n > 1 then +begin +declare x, y bigint unsigned; +declare c cursor for select f from fib order by f desc limit 2; +open c; +fetch c into y; +fetch c into x; +close c; +insert into fib values (x+y); +call fib(n-1); +end; +end if; +end| +set @@max_sp_recursion_depth= 20| +insert into fib values (0), (1)| +call fib(3)| +select * from fib order by f asc| +f +0 +1 +1 +2 +delete from fib| +insert into fib values (0), (1)| +call fib(20)| +select * from fib order by f asc| +f +0 +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 +144 +233 +377 +610 +987 +1597 +2584 +4181 +6765 +drop table fib| +drop procedure fib| +set @@max_sp_recursion_depth= 0| drop procedure if exists bar| create procedure bar(x char(16), y int) comment "111111111111" sql security invoker @@ -1479,6 +1545,52 @@ select @x2| @x2 2 drop procedure bug2260| +drop procedure if exists bug2267_1| +create procedure bug2267_1() +begin +show procedure status; +end| +drop procedure if exists bug2267_2| +create procedure bug2267_2() +begin +show function status; +end| +drop procedure if exists bug2267_3| +create procedure bug2267_3() +begin +show create procedure bug2267_1; +end| +drop procedure if exists bug2267_4| +drop function if exists bug2267_4| +create procedure bug2267_4() +begin +show create function bug2267_4; +end| +create function bug2267_4() returns int return 100| +call bug2267_1()| +Db Name Type Definer Modified Created Security_type Comment +test bug2267_1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER +test bug2267_2 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER +test bug2267_3 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER +test bug2267_4 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER +call bug2267_2()| +Db Name Type Definer Modified Created Security_type Comment +test bug2267_4 FUNCTION root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER +call bug2267_3()| +Procedure sql_mode Create Procedure +bug2267_1 CREATE PROCEDURE `bug2267_1`() +begin +show procedure status; +end +call bug2267_4()| +Function sql_mode Create Function +bug2267_4 CREATE FUNCTION `bug2267_4`() RETURNS int(11) +return 100 +drop procedure bug2267_1| +drop procedure bug2267_2| +drop procedure bug2267_3| +drop procedure bug2267_4| +drop function bug2267_4| drop procedure if exists bug2227| create procedure bug2227(x int) begin @@ -1490,6 +1602,18 @@ call bug2227(9)| 1.3 x y 42 z 1.3 9 2.6 42 zzz drop procedure bug2227| +drop procedure if exists bug2614| +create procedure bug2614() +begin +drop table if exists t3; +create table t3 (id int default '0' not null); +insert into t3 select 12; +insert into t3 select * from t3; +end| +call bug2614()| +call bug2614()| +drop table t3| +drop procedure bug2614| drop function if exists bug2674| create function bug2674() returns int return @@sort_buffer_size| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index fba3cfcbfbc..d979c407b37 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -1211,15 +1211,13 @@ begin end if; end| select f5(1)| -# This should generate an error about insuficient number of tables locked -# Now this crash server ---disable_parsing # until bug#11394 fix ---error 1100 +# Since currently recursive functions are disallowed ER_SP_NO_RECURSION +# error will be returned, once we will allow them error about +# insufficient number of locked tables will be returned instead. +--error ER_SP_NO_RECURSION select f5(2)| -# But now it simply miserably fails because we are trying to use the same -# lex on the next iteration :/ It should generate some error too... +--error ER_SP_NO_RECURSION select f5(3)| ---enable_parsing # OTOH this should work create function f6() returns int @@ -1265,13 +1263,12 @@ select * from v1| # views and functions ? create function f1() returns int return (select sum(data) from t1) + (select sum(data) from v1)| -# This queries will crash server because we can't use LEX in -# reenterable fashion yet. Patch disabling recursion will heal this. ---disable_parsing +--error ER_SP_NO_RECURSION select f1()| +--error ER_SP_NO_RECURSION select * from v1| +--error ER_SP_NO_RECURSION select * from v2| ---enable_parsing # Back to the normal cases drop function f1| create function f1() returns int @@ -1289,9 +1286,7 @@ select *, f0() from v0| # # Let us test how well prelocking works with explicit LOCK TABLES. # -# Nowdays we have to lock mysql.proc to be able to read SP definitions. -# But Monty was going to fix this. -lock tables t1 read, t1 as t11 read, mysql.proc read| +lock tables t1 read, t1 as t11 read| # These should work well select f3()| select id, f3() from t1 as t11| @@ -1481,9 +1476,6 @@ show procedure status like '%p%'| # Fibonacci, for recursion test. (Yet Another Numerical series :) # -# This part of test is disabled until we implement support for -# recursive stored procedures. ---disable_parsing --disable_warnings drop table if exists fib| --enable_warnings @@ -1512,6 +1504,9 @@ begin end if; end| +# Enable recursion +set @@max_sp_recursion_depth= 20| + # Minimum test: recursion of 3 levels insert into fib values (0), (1)| @@ -1531,7 +1526,7 @@ call fib(20)| select * from fib order by f asc| drop table fib| drop procedure fib| ---enable_parsing +set @@max_sp_recursion_depth= 0| # # Comment & suid @@ -1800,16 +1795,8 @@ select @x2| drop procedure bug2260| # -# BUG#2267 +# BUG#2267 "Lost connect if stored procedure has SHOW FUNCTION STATUS" # -# NOTE: This test case will be fixed as soon as Monty -# will allow to open mysql.proc table under LOCK TABLES -# without mentioning in lock list. -# -# FIXME: Other solution would be to use preopened proc table -# instead of opening it anew. -# ---disable_parsing --disable_warnings drop procedure if exists bug2267_1| --enable_warnings @@ -1836,11 +1823,13 @@ end| --disable_warnings drop procedure if exists bug2267_4| +drop function if exists bug2267_4| --enable_warnings create procedure bug2267_4() begin - show create function fac; + show create function bug2267_4; end| +create function bug2267_4() returns int return 100| --replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' call bug2267_1()| @@ -1853,7 +1842,7 @@ drop procedure bug2267_1| drop procedure bug2267_2| drop procedure bug2267_3| drop procedure bug2267_4| ---enable_parsing +drop function bug2267_4| # # BUG#2227 @@ -1873,23 +1862,16 @@ call bug2227(9)| drop procedure bug2227| # -# BUG#2614 +# BUG#2614 "Stored procedure with INSERT ... SELECT that does not +# contain any tables crashes server" # -# QQ The second insert doesn't work with temporary tables (it was an -# QQ ordinary table before we changed the locking scheme). It results -# QQ in an error: 1137: Can't reopen table: 't3' -# QQ which is a known limit with temporary tables. -# QQ For this reason we can't run this test any more (i.e., if we modify -# QQ it, it's no longer a test case for the bug), but we keep it here -# QQ anyway, for tracability. ---disable_parsing --disable_warnings drop procedure if exists bug2614| --enable_warnings create procedure bug2614() begin - drop temporary table if exists t3; - create temporary table t3 (id int default '0' not null); + drop table if exists t3; + create table t3 (id int default '0' not null); insert into t3 select 12; insert into t3 select * from t3; end| @@ -1898,9 +1880,8 @@ end| call bug2614()| --enable_warnings call bug2614()| -drop temporary table t3| +drop table t3| drop procedure bug2614| ---enable_parsing # # BUG#2674 From 8778a5df5ad07f16bc1bb07bed7a5b91ec82d740 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 26 Nov 2005 19:36:11 +0100 Subject: [PATCH 26/29] followup for for the bug#5686 --- myisam/ft_parser.c | 4 +++- mysql-test/r/fulltext.result | 3 +++ mysql-test/t/fulltext.test | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/myisam/ft_parser.c b/myisam/ft_parser.c index 8e4769ebc75..fad8b5c4273 100644 --- a/myisam/ft_parser.c +++ b/myisam/ft_parser.c @@ -147,8 +147,10 @@ byte ft_get_word(CHARSET_INFO *cs, byte **start, byte *end, for (word->pos=doc; docprev='A'; /* be sure *prev is true_word_char */ word->len= (uint)(doc-word->pos) - mwc; diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 87551f96a13..ebd6880a10e 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -432,4 +432,7 @@ INSERT INTO t1 VALUES('testword\'\''); SELECT a FROM t1 WHERE MATCH a AGAINST('testword' IN BOOLEAN MODE); a testword'' +SELECT a FROM t1 WHERE MATCH a AGAINST('testword\'\'' IN BOOLEAN MODE); +a +testword'' DROP TABLE t1; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 7c7927b638b..1399b9bfdff 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -354,6 +354,7 @@ SET myisam_repair_threads=@@global.myisam_repair_threads; # INSERT INTO t1 VALUES('testword\'\''); SELECT a FROM t1 WHERE MATCH a AGAINST('testword' IN BOOLEAN MODE); +SELECT a FROM t1 WHERE MATCH a AGAINST('testword\'\'' IN BOOLEAN MODE); DROP TABLE t1; # End of 4.1 tests From a9af48e9fc0b6bf91b272516dc8ec485b4faf7f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Nov 2005 12:41:44 +0400 Subject: [PATCH 27/29] item.cc, item.h: Fixing Item_param::safe_charset_converter to do less "new"s. sql/item.h: Fixing Item_param::safe_charset_converter to do less "new"s. sql/item.cc: Fixing Item_param::safe_charset_converter to do less "new"s. --- sql/item.cc | 26 ++++++++++---------------- sql/item.h | 4 ++++ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 1767f9d97c1..0e45b8f2259 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -700,23 +700,15 @@ Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs) { if (const_item()) { - Item_string *conv; uint cnv_errors; - char buf[MAX_FIELD_WIDTH]; - String tmp(buf, sizeof(buf), &my_charset_bin); - String cstr, *ostr= val_str(&tmp); - /* - As safe_charset_converter is not executed for - a parameter bound to NULL, ostr should never be 0. - */ - cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &cnv_errors); - if (cnv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(), - cstr.charset(), - collation.derivation))) - return NULL; - conv->str_value.copy(); - conv->str_value.mark_as_const(); - return conv; + String *ostr= val_str(&cnvstr); + cnvitem->str_value.copy(ostr->ptr(), ostr->length(), + ostr->charset(), tocs, &cnv_errors); + if (cnv_errors) + return NULL; + cnvitem->str_value.mark_as_const(); + cnvitem->max_length= cnvitem->str_value.numchars() * tocs->mbmaxlen; + return cnvitem; } return NULL; } @@ -2098,6 +2090,8 @@ Item_param::Item_param(unsigned pos_in_query_arg) : value is set. */ maybe_null= 1; + cnvitem= new Item_string("", 0, &my_charset_bin, DERIVATION_COERCIBLE); + cnvstr.set(cnvbuf, sizeof(cnvbuf), &my_charset_bin); } diff --git a/sql/item.h b/sql/item.h index 8bc659c3060..2b3a1ab3edb 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1075,7 +1075,11 @@ public: class Item_param :public Item { + char cnvbuf[MAX_FIELD_WIDTH]; + String cnvstr; + Item *cnvitem; public: + enum enum_item_param_state { NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE, From 12de238b092c1d1d61b0707050e9fca841bd7243 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Nov 2005 17:06:57 +0400 Subject: [PATCH 28/29] grant.result: After merge fix. mysql-test/r/grant.result: After merge fix. --- mysql-test/r/grant.result | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index a9f90e24556..448847bc919 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -594,3 +594,24 @@ flush privileges; set @user123="non-existent"; select * from mysql.db where user=@user123; Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv +set names koi8r; +create database ÂÄ; +grant select on ÂÄ.* to root@localhost; +select hex(Db) from mysql.db where Db='ÂÄ'; +hex(Db) +D0B1D0B4 +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost' +flush privileges; +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost' +drop database ÂÄ; +revoke all privileges on ÂÄ.* from root@localhost; +show grants for root@localhost; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +set names latin1; From c565ca2bf2a0e36df5587433446640de3c9d45cd Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 Nov 2005 16:28:00 +0100 Subject: [PATCH 29/29] Include libyassl.la and libtaocrypt.la in libmysqlclient.la config/ac-macros/yassl.m4: Specify path to yassl libs libmysql/Makefile.am: Add yassl .la libs to libmysqlclient.la --- config/ac-macros/yassl.m4 | 2 ++ libmysql/Makefile.am | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/ac-macros/yassl.m4 b/config/ac-macros/yassl.m4 index d1216554862..77208faee0c 100644 --- a/config/ac-macros/yassl.m4 +++ b/config/ac-macros/yassl.m4 @@ -17,6 +17,7 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [ yassl_dir="extra/yassl" yassl_libs="-L\$(top_srcdir)/extra/yassl/src -lyassl -L\$(top_srcdir)/extra/yassl/taocrypt/src -ltaocrypt" yassl_includes="-I\$(top_srcdir)/extra/yassl/include" + yassl_libs_with_path="\$(top_srcdir)/extra/yassl/src/libyassl.la \$(top_srcdir)/extra/yassl/taocrypt/src/libtaocrypt.la" AC_DEFINE([HAVE_OPENSSL], [1], [Defined by configure. Using yaSSL for OpenSSL emulation.]) AC_DEFINE([HAVE_YASSL], [1], [Defined by configure. Using yaSSL for OpenSSL emulation.]) # System specific checks @@ -35,6 +36,7 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [ AC_MSG_RESULT(no) fi AC_SUBST(yassl_libs) + AC_SUBST(yassl_libs_with_path) AC_SUBST(yassl_includes) AC_SUBST(yassl_dir) AM_CONDITIONAL([HAVE_YASSL], [ test "with_yassl" = "yes" ]) diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index 319a9913255..a3e16b521a9 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -22,14 +22,14 @@ target = libmysqlclient.la target_defs = -DUNDEF_THREADS_HACK -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@ -LIBS = @CLIENT_LIBS@ @yassl_libs@ +LIBS = @CLIENT_LIBS@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ $(openssl_includes) $(yassl_includes) @ZLIB_INCLUDES@ include $(srcdir)/Makefile.shared libmysqlclient_la_SOURCES = $(target_sources) -libmysqlclient_la_LIBADD = $(target_libadd) +libmysqlclient_la_LIBADD = $(target_libadd) $(yassl_libs_with_path) libmysqlclient_la_LDFLAGS = $(target_ldflags) EXTRA_DIST = Makefile.shared libmysql.def noinst_HEADERS = client_settings.h