From 05bef7884abf7ebc4dfaed6ff0b9611f7c52d1cb Mon Sep 17 00:00:00 2001 From: "Kristofer.Pettersson@naruto." <> Date: Fri, 16 Mar 2007 14:25:11 +0100 Subject: [PATCH 01/14] Bug#20777 Function w BIGINT UNSIGNED shows diff. behaviour with and without --ps-protocol - Stored procedures returning unsinged values returns signed values if text protocol is used. The reason is that the stored proceedure item Item_func_sp wasn't initializing the member variables properly based on the information contained in the associated result field. - The patch is to upon field-item association, ::fix_fields, initialize the member variables in appropriate order. - Field type of an Item_func_sp was hard coded to MYSQL_TYPE_VARCHAR. This is changed to return the type of the actual result field. - Member function name sp_result_field was refactored to the more appropriate init_result_field. - Member function name find_and_check_access was refactored to sp_check_access. --- mysql-test/r/sp.result | 88 +++++++++++ mysql-test/t/sp.test | 60 +++++++- sql/item_func.cc | 325 ++++++++++++++++++++--------------------- sql/item_func.h | 31 ++-- 4 files changed, 319 insertions(+), 185 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 8e3c057cc62..248df2c38d0 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5741,4 +5741,92 @@ END| CALL bug24117()| DROP PROCEDURE bug24117| DROP TABLE t3| +drop function if exists bug20777| +drop table if exists examplebug20777| +create function bug20777(f1 bigint unsigned) returns bigint unsigned +begin +set f1 = (f1 - 10); set f1 = (f1 + 10); +return f1; +end| +select bug20777(9223372036854775803) as '9223372036854775803 2**63-5'; +9223372036854775803 2**63-5 +9223372036854775803 +select bug20777(9223372036854775804) as '9223372036854775804 2**63-4'; +9223372036854775804 2**63-4 +9223372036854775804 +select bug20777(9223372036854775805) as '9223372036854775805 2**63-3'; +9223372036854775805 2**63-3 +9223372036854775805 +select bug20777(9223372036854775806) as '9223372036854775806 2**63-2'; +9223372036854775806 2**63-2 +9223372036854775806 +select bug20777(9223372036854775807) as '9223372036854775807 2**63-1'; +9223372036854775807 2**63-1 +9223372036854775807 +select bug20777(9223372036854775808) as '9223372036854775808 2**63+0'; +9223372036854775808 2**63+0 +9223372036854775808 +select bug20777(9223372036854775809) as '9223372036854775809 2**63+1'; +9223372036854775809 2**63+1 +9223372036854775809 +select bug20777(9223372036854775810) as '9223372036854775810 2**63+2'; +9223372036854775810 2**63+2 +9223372036854775810 +select bug20777(-9223372036854775808) as 'lower bounds signed bigint'; +lower bounds signed bigint +0 +select bug20777(9223372036854775807) as 'upper bounds signed bigint'; +upper bounds signed bigint +9223372036854775807 +select bug20777(0) as 'lower bounds unsigned bigint'; +lower bounds unsigned bigint +0 +select bug20777(18446744073709551615) as 'upper bounds unsigned bigint'; +upper bounds unsigned bigint +18446744073709551615 +select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1'; +upper bounds unsigned bigint + 1 +18446744073709551615 +select bug20777(-1) as 'lower bounds unsigned bigint - 1'; +lower bounds unsigned bigint - 1 +0 +select bug20777(1.84e+19) as 'submitter value, 1.84e19'; +submitter value, 1.84e19 +9223372036854775808 +create table examplebug20777 as select +0 as 'i', +bug20777(9223372036854775806) as '2**63-2', +bug20777(9223372036854775807) as '2**63-1', +bug20777(9223372036854775808) as '2**63', +bug20777(9223372036854775809) as '2**63+1', +bug20777(18446744073709551614) as '2**64-2', +bug20777(18446744073709551615) as '2**64-1', +bug20777(18446744073709551616) as '2**64', +bug20777(0) as '0', +bug20777(-1) as '-1'; +insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1); +show create table examplebug20777; +Table Create Table +examplebug20777 CREATE TABLE `examplebug20777` ( + `i` int(1) NOT NULL default '0', + `2**63-2` bigint(20) unsigned default NULL, + `2**63-1` bigint(20) unsigned default NULL, + `2**63` bigint(20) unsigned default NULL, + `2**63+1` bigint(20) unsigned default NULL, + `2**64-2` bigint(20) unsigned default NULL, + `2**64-1` bigint(20) unsigned default NULL, + `2**64` bigint(20) unsigned default NULL, + `0` bigint(20) unsigned default NULL, + `-1` bigint(20) unsigned default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from examplebug20777 order by i; +i 2**63-2 2**63-1 2**63 2**63+1 2**64-2 2**64-1 2**64 0 -1 +0 9223372036854775806 9223372036854775807 9223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 18446744073709551615 0 0 +1 9223372036854775806 9223372036854775807 223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 8446744073709551616 0 0 +drop table examplebug20777; +select bug20777(18446744073709551613)+1; +bug20777(18446744073709551613)+1 +18446744073709551614 +drop function bug20777; +End of 5.0 tests. drop table t1,t2; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index cfa4937e050..1945d5daf4d 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -6715,9 +6715,56 @@ DROP PROCEDURE bug24117| DROP TABLE t3| # -# NOTE: The delimiter is `|`, and not `;`. It is changed to `;` -# at the end of the file! +# Bug#20777: Function w BIGINT UNSIGNED shows diff. behaviour --ps-protocol # +--disable_warnings +drop function if exists bug20777| +drop table if exists examplebug20777| +--enabled_warnings +create function bug20777(f1 bigint unsigned) returns bigint unsigned +begin + set f1 = (f1 - 10); set f1 = (f1 + 10); +return f1; +end| +delimiter ;| +select bug20777(9223372036854775803) as '9223372036854775803 2**63-5'; +select bug20777(9223372036854775804) as '9223372036854775804 2**63-4'; +select bug20777(9223372036854775805) as '9223372036854775805 2**63-3'; +select bug20777(9223372036854775806) as '9223372036854775806 2**63-2'; +select bug20777(9223372036854775807) as '9223372036854775807 2**63-1'; +select bug20777(9223372036854775808) as '9223372036854775808 2**63+0'; +select bug20777(9223372036854775809) as '9223372036854775809 2**63+1'; +select bug20777(9223372036854775810) as '9223372036854775810 2**63+2'; +select bug20777(-9223372036854775808) as 'lower bounds signed bigint'; +select bug20777(9223372036854775807) as 'upper bounds signed bigint'; +select bug20777(0) as 'lower bounds unsigned bigint'; +select bug20777(18446744073709551615) as 'upper bounds unsigned bigint'; +select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1'; +select bug20777(-1) as 'lower bounds unsigned bigint - 1'; +select bug20777(1.84e+19) as 'submitter value, 1.84e19'; + +create table examplebug20777 as select + 0 as 'i', + bug20777(9223372036854775806) as '2**63-2', + bug20777(9223372036854775807) as '2**63-1', + bug20777(9223372036854775808) as '2**63', + bug20777(9223372036854775809) as '2**63+1', + bug20777(18446744073709551614) as '2**64-2', + bug20777(18446744073709551615) as '2**64-1', + bug20777(18446744073709551616) as '2**64', + bug20777(0) as '0', + bug20777(-1) as '-1'; +insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1); +show create table examplebug20777; +select * from examplebug20777 order by i; + +drop table examplebug20777; +select bug20777(18446744073709551613)+1; +drop function bug20777; +delimiter |; + +### +--echo End of 5.0 tests. # # BUG#NNNN: New bug synopsis @@ -6726,8 +6773,13 @@ DROP TABLE t3| #drop procedure if exists bugNNNN| #--enable_warnings #create procedure bugNNNN... - +# # Add bugs above this line. Use existing tables t1 and t2 when -# practical, or create table t3, t4 etc temporarily (and drop them). +# practical, or create table t3,t4 etc temporarily (and drop them). +# NOTE: The delimiter is `|`, and not `;`. It is changed to `;` +# at the end of the file! +# + delimiter ;| drop table t1,t2; + diff --git a/sql/item_func.cc b/sql/item_func.cc index 32cc90b96d6..a27b7b6bcc2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4979,8 +4979,7 @@ longlong Item_func_row_count::val_int() Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name) - :Item_func(), context(context_arg), m_name(name), m_sp(NULL), - result_field(NULL) + :Item_func(), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL) { maybe_null= 1; m_name->init_qname(current_thd); @@ -4990,21 +4989,21 @@ Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name) Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name, List &list) - :Item_func(list), context(context_arg), m_name(name), m_sp(NULL), - result_field(NULL) + :Item_func(list), context(context_arg), m_name(name), m_sp(NULL),sp_result_field(NULL) { maybe_null= 1; m_name->init_qname(current_thd); dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)); } + void Item_func_sp::cleanup() { - if (result_field) + if (sp_result_field) { - delete result_field; - result_field= NULL; + delete sp_result_field; + sp_result_field= NULL; } m_sp= NULL; dummy_table->s= NULL; @@ -5033,82 +5032,117 @@ Item_func_sp::func_name() const } -Field * -Item_func_sp::sp_result_field(void) const + +/** + @brief Initialize the result field by creating a temporary dummy table + and assign it to a newly created field object. Meta data used to + create the field is fetched from the sp_head belonging to the stored + proceedure found in the stored procedure functon cache. + + @note This function should be called from fix_fields to init the result + field. It is some what related to Item_field. + + @see Item_field + + @param thd A pointer to the session and thread context. + + @return Function return error status. + @retval TRUE is returned on an error + @retval FALSE is returned on success. +*/ +bool +Item_func_sp::init_result_field(THD *thd) { - Field *field; - DBUG_ENTER("Item_func_sp::sp_result_field"); - DBUG_PRINT("info", ("sp: %s, flags: %x, level: %lu", - (m_sp ? "YES" : "NO"), - (m_sp ? m_sp->m_flags : (uint)0), - (m_sp ? m_sp->m_recursion_level : (ulong)0))); + DBUG_ENTER("Item_func_sp::init_result_field"); + + char *empty_name= (char *) ""; + TABLE_SHARE *share; - if (!m_sp) - { - THD *thd= current_thd; - if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, - &thd->sp_func_cache, TRUE))) - { - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); - DBUG_RETURN(0); - } - } - if (!dummy_table->s) - { - char *empty_name= (char *) ""; - TABLE_SHARE *share; - dummy_table->s= share= &dummy_table->share_not_to_be_used; - dummy_table->alias = empty_name; - dummy_table->maybe_null = maybe_null; - dummy_table->in_use= current_thd; - dummy_table->copy_blobs= TRUE; - share->table_cache_key = empty_name; - share->table_name = empty_name; - } - if (!(field= m_sp->create_result_field(max_length, name, dummy_table))) - my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); + DBUG_ASSERT(m_sp == NULL); + DBUG_ASSERT(sp_result_field == NULL); + DBUG_ASSERT(dummy_table->s == NULL); - DBUG_RETURN(field); + if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, + &thd->sp_func_cache, TRUE))) + { + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); + context->process_error(thd); + DBUG_RETURN(TRUE); + } + + /* + A Field need to be attached to a Table. + Below we "create" a dummy table by initializing + the needed pointers. + */ + dummy_table->s= share= &dummy_table->share_not_to_be_used; + dummy_table->alias = empty_name; + dummy_table->maybe_null = maybe_null; + dummy_table->in_use= thd; + dummy_table->copy_blobs= TRUE; + share->table_cache_key = empty_name; + share->table_name = empty_name; + + if (!(sp_result_field= m_sp->create_result_field(max_length, name, dummy_table))) + { + DBUG_RETURN(TRUE); + } + + if (sp_result_field->pack_length() > sizeof(result_buf)) + { + sp_result_field->move_field(sql_alloc(sp_result_field->pack_length())); + } else { + sp_result_field->move_field(result_buf); + } + + sp_result_field->null_ptr= (uchar *) &null_value; + sp_result_field->null_bit= 1; + + + DBUG_RETURN(FALSE); } +/** + @brief Initialize local members with values from the Field interface. -/* - Execute function & store value in field + @note called from Item::fix_fields. +*/ +void Item_func_sp::fix_length_and_dec() +{ + DBUG_ENTER("Item_func_sp::fix_length_and_dec"); - RETURN - 0 value <> NULL - 1 value = NULL or error + DBUG_ASSERT(sp_result_field); + decimals= sp_result_field->decimals(); + max_length= sp_result_field->field_length; + collation.set(sp_result_field->charset()); + maybe_null= 1; + unsigned_flag= test(sp_result_field->flags & UNSIGNED_FLAG); + + DBUG_VOID_RETURN; +} + +/** + @brief Execute function & store value in field. + + @return Function returns error status. + @retval FALSE on success. + @retval TRUE if an error occurred. */ bool -Item_func_sp::execute(Field **flp) +Item_func_sp::execute() { THD *thd= current_thd; - Field *f; - + /* Get field in virtual tmp table to store result. Create the field if invoked first time. */ - - if (!(f= *flp)) - { - if (!(*flp= f= sp_result_field())) - { - /* Error set by sp_result_field() */ - null_value= 1; - return TRUE; - } - f->move_field((f->pack_length() > sizeof(result_buf)) ? - sql_alloc(f->pack_length()) : result_buf); - f->null_ptr= (uchar *)&null_value; - f->null_bit= 1; - } /* Execute function and store the return value in the field. */ - if (execute_impl(thd, f)) + if (execute_impl(thd)) { null_value= 1; context->process_error(thd); @@ -5117,14 +5151,24 @@ Item_func_sp::execute(Field **flp) /* Check that the field (the value) is not NULL. */ - null_value= f->is_null(); + null_value= sp_result_field->is_null(); return null_value; } +/** + @brief Execute function and store the return value in the field. + + @note This function was intended to be the concrete implementation of + the interface function execute. This was never realized. + + @return The error state. + @retval FALSE on success + @retval TRUE if an error occurred. +*/ bool -Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) +Item_func_sp::execute_impl(THD *thd) { bool err_status= TRUE; Sub_statement_state statement_state; @@ -5141,7 +5185,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) thd->security_ctx= context->security_ctx; } #endif - if (find_and_check_access(thd)) + if (sp_check_access(thd)) goto error; /* @@ -5150,7 +5194,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) function call into binlog. */ thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION); - err_status= m_sp->execute_function(thd, args, arg_count, return_value_fld); + err_status= m_sp->execute_function(thd, args, arg_count, sp_result_field); thd->restore_sub_statement_state(&statement_state); error: @@ -5165,15 +5209,9 @@ error: void Item_func_sp::make_field(Send_field *tmp_field) { - Field *field; DBUG_ENTER("Item_func_sp::make_field"); - if ((field= sp_result_field())) - { - field->make_field(tmp_field); - delete field; - DBUG_VOID_RETURN; - } - init_make_field(tmp_field, MYSQL_TYPE_VARCHAR); + DBUG_ASSERT(sp_result_field); + sp_result_field->make_field(tmp_field); DBUG_VOID_RETURN; } @@ -5181,67 +5219,20 @@ Item_func_sp::make_field(Send_field *tmp_field) enum enum_field_types Item_func_sp::field_type() const { - Field *field; DBUG_ENTER("Item_func_sp::field_type"); - - if (result_field) - DBUG_RETURN(result_field->type()); - if ((field= sp_result_field())) - { - enum_field_types result= field->type(); - delete field; - DBUG_RETURN(result); - } - DBUG_RETURN(MYSQL_TYPE_VARCHAR); + DBUG_ASSERT(sp_result_field); + DBUG_RETURN(sp_result_field->type()); } - Item_result Item_func_sp::result_type() const { - Field *field; DBUG_ENTER("Item_func_sp::result_type"); DBUG_PRINT("info", ("m_sp = %p", m_sp)); - - if (result_field) - DBUG_RETURN(result_field->result_type()); - if ((field= sp_result_field())) - { - Item_result result= field->result_type(); - delete field; - DBUG_RETURN(result); - } - DBUG_RETURN(STRING_RESULT); + DBUG_ASSERT(sp_result_field); + DBUG_RETURN(sp_result_field->result_type()); } -void -Item_func_sp::fix_length_and_dec() -{ - Field *field; - DBUG_ENTER("Item_func_sp::fix_length_and_dec"); - - if (result_field) - { - decimals= result_field->decimals(); - max_length= result_field->field_length; - collation.set(result_field->charset()); - DBUG_VOID_RETURN; - } - - if (!(field= sp_result_field())) - { - context->process_error(current_thd); - DBUG_VOID_RETURN; - } - decimals= field->decimals(); - max_length= field->field_length; - collation.set(field->charset()); - maybe_null= 1; - delete field; - DBUG_VOID_RETURN; -} - - longlong Item_func_found_rows::val_int() { DBUG_ASSERT(fixed == 1); @@ -5252,57 +5243,39 @@ longlong Item_func_found_rows::val_int() Field * Item_func_sp::tmp_table_field(TABLE *t_arg) { - Field *field= 0; DBUG_ENTER("Item_func_sp::tmp_table_field"); - if (m_sp) - field= m_sp->create_result_field(max_length, (const char*) name, t_arg); - - if (!field) - field= Item_func::tmp_table_field(t_arg); - - if (!field) - my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); - - DBUG_RETURN(field); + DBUG_ASSERT(sp_result_field); + DBUG_RETURN(sp_result_field); } -/* - Find the function and check access rights to the function - - SYNOPSIS - find_and_check_access() - thd thread handler - - RETURN - FALSE Access granted - TRUE Requested access can't be granted or function doesn't exists - - NOTES - Checks if requested access to function can be granted to user. +/** + @brief Checks if requested access to function can be granted to user. If function isn't found yet, it searches function first. If function can't be found or user don't have requested access error is raised. + + @param thd thread handler + + @return Indication if the access was granted or not. + @retval FALSE Access is granted. + @retval TRUE Requested access can't be granted or function doesn't exists. + */ bool -Item_func_sp::find_and_check_access(THD *thd) +Item_func_sp::sp_check_access(THD *thd) { - if (! m_sp && ! (m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, - &thd->sp_func_cache, TRUE))) - { - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); - return TRUE; - } - + DBUG_ENTER("Item_func_sp::sp_check_access"); + DBUG_ASSERT(m_sp); #ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_routine_access(thd, EXECUTE_ACL, m_sp->m_db.str, m_sp->m_name.str, 0, FALSE)) - return TRUE; + DBUG_RETURN(TRUE); #endif - return FALSE; + DBUG_RETURN(FALSE); } @@ -5310,9 +5283,25 @@ bool Item_func_sp::fix_fields(THD *thd, Item **ref) { bool res; + DBUG_ENTER("Item_func_sp::fix_fields"); DBUG_ASSERT(fixed == 0); + + /* + We must call init_result_field before Item_func::fix_fields() + to make m_sp and result_field members available to fix_length_and_dec(), + which is called from Item_func::fix_fields(). + */ + res= init_result_field(thd); + + if (res) + DBUG_RETURN(res); + res= Item_func::fix_fields(thd, ref); - if (!res && thd->lex->view_prepare_mode) + + if (res) + DBUG_RETURN(res); + + if (thd->lex->view_prepare_mode) { /* Here we check privileges of the stored routine only during view @@ -5324,15 +5313,17 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) good idea especially if the view has SQL SECURITY DEFINER and the used stored procedure has SQL SECURITY DEFINER. */ - res= find_and_check_access(thd); + res= sp_check_access(thd); #ifndef NO_EMBEDDED_ACCESS_CHECKS + /* + Try to set and restore the security context to see whether it's valid + */ Security_context *save_secutiry_ctx; - if (!res && !(res= set_routine_security_ctx(thd, m_sp, false, - &save_secutiry_ctx))) - { + res= set_routine_security_ctx(thd, m_sp, false, &save_secutiry_ctx); + if (!res) sp_restore_security_context(thd, save_secutiry_ctx); - } + #endif /* ! NO_EMBEDDED_ACCESS_CHECKS */ } - return res; + DBUG_RETURN(res); } diff --git a/sql/item_func.h b/sql/item_func.h index 68591f9c6f5..6a619327590 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1405,12 +1405,15 @@ private: sp_name *m_name; mutable sp_head *m_sp; TABLE *dummy_table; - Field *result_field; char result_buf[64]; + /* + The result field of the concrete stored function. + */ + Field *sp_result_field; - bool execute(Field **flp); - bool execute_impl(THD *thd, Field *return_value_fld); - Field *sp_result_field(void) const; + bool execute(); + bool execute_impl(THD *thd); + bool init_result_field(THD *thd); public: @@ -1436,23 +1439,23 @@ public: longlong val_int() { - if (execute(&result_field)) + if (execute()) return (longlong) 0; - return result_field->val_int(); + return sp_result_field->val_int(); } double val_real() { - if (execute(&result_field)) + if (execute()) return 0.0; - return result_field->val_real(); + return sp_result_field->val_real(); } my_decimal *val_decimal(my_decimal *dec_buf) { - if (execute(&result_field)) + if (execute()) return NULL; - return result_field->val_decimal(dec_buf); + return sp_result_field->val_decimal(dec_buf); } String *val_str(String *str) @@ -1461,7 +1464,7 @@ public: char buff[20]; buf.set(buff, 20, str->charset()); buf.length(0); - if (execute(&result_field)) + if (execute()) return NULL; /* result_field will set buf pointing to internal buffer @@ -1469,7 +1472,7 @@ public: when SP is executed. In order to prevent occasional corruption of returned value, we make here a copy. */ - result_field->val_str(&buf); + sp_result_field->val_str(&buf); str->copy(buf); return str; } @@ -1477,11 +1480,11 @@ public: virtual bool change_context_processor(byte *cntx) { context= (Name_resolution_context *)cntx; return FALSE; } - void fix_length_and_dec(); - bool find_and_check_access(THD * thd); + bool sp_check_access(THD * thd); virtual enum Functype functype() const { return FUNC_SP; } bool fix_fields(THD *thd, Item **ref); + void fix_length_and_dec(void); bool is_expensive() { return 1; } }; From 13af4d5417c8269a0a1b931cf627fb861acd9aad Mon Sep 17 00:00:00 2001 From: "Kristofer.Pettersson@naruto." <> Date: Mon, 19 Mar 2007 16:45:09 +0100 Subject: [PATCH 02/14] Manual merge --- mysql-test/r/sp.result | 20 ++++++++++---------- sql/item_func.cc | 11 ++++++----- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 033409f3d77..1c91c964cb9 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5899,16 +5899,16 @@ insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, show create table examplebug20777; Table Create Table examplebug20777 CREATE TABLE `examplebug20777` ( - `i` int(1) NOT NULL default '0', - `2**63-2` bigint(20) unsigned default NULL, - `2**63-1` bigint(20) unsigned default NULL, - `2**63` bigint(20) unsigned default NULL, - `2**63+1` bigint(20) unsigned default NULL, - `2**64-2` bigint(20) unsigned default NULL, - `2**64-1` bigint(20) unsigned default NULL, - `2**64` bigint(20) unsigned default NULL, - `0` bigint(20) unsigned default NULL, - `-1` bigint(20) unsigned default NULL + `i` int(1) NOT NULL DEFAULT '0', + `2**63-2` bigint(20) unsigned DEFAULT NULL, + `2**63-1` bigint(20) unsigned DEFAULT NULL, + `2**63` bigint(20) unsigned DEFAULT NULL, + `2**63+1` bigint(20) unsigned DEFAULT NULL, + `2**64-2` bigint(20) unsigned DEFAULT NULL, + `2**64-1` bigint(20) unsigned DEFAULT NULL, + `2**64` bigint(20) unsigned DEFAULT NULL, + `0` bigint(20) unsigned DEFAULT NULL, + `-1` bigint(20) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 select * from examplebug20777 order by i; i 2**63-2 2**63-1 2**63 2**63+1 2**64-2 2**64-1 2**64 0 -1 diff --git a/sql/item_func.cc b/sql/item_func.cc index 2cb67cb28a4..601682e0313 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5009,7 +5009,7 @@ Item_func_sp::cleanup() sp_result_field= NULL; } m_sp= NULL; - dummy_table->s= NULL; + dummy_table->alias= NULL; Item_func::cleanup(); } @@ -5057,13 +5057,13 @@ bool Item_func_sp::init_result_field(THD *thd) { DBUG_ENTER("Item_func_sp::init_result_field"); + + LEX_STRING empty_name= { STRING_WITH_LEN("") }; - char *empty_name= (char *) ""; TABLE_SHARE *share; DBUG_ASSERT(m_sp == NULL); DBUG_ASSERT(sp_result_field == NULL); - DBUG_ASSERT(dummy_table->s == NULL); if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, &thd->sp_func_cache, TRUE))) @@ -5078,8 +5078,9 @@ Item_func_sp::init_result_field(THD *thd) Below we "create" a dummy table by initializing the needed pointers. */ - dummy_table->s= share= &dummy_table->share_not_to_be_used; - dummy_table->alias = empty_name; + + share= dummy_table->s; + dummy_table->alias = ""; dummy_table->maybe_null = maybe_null; dummy_table->in_use= thd; dummy_table->copy_blobs= TRUE; From 094612854d44012aa5127a01ec2cc03d26abc1ef Mon Sep 17 00:00:00 2001 From: "kostja@bodhi.local" <> Date: Fri, 23 Mar 2007 18:14:03 +0300 Subject: [PATCH 03/14] Trivial cleanups and whitespace change in Event Scheduler code. A larger patch is to come, this is to exclude rudimentary changes from it. --- sql/event_data_objects.cc | 23 +++++++++++------------ sql/event_data_objects.h | 20 +------------------- sql/event_db_repository.cc | 24 ++++++++++++------------ sql/event_db_repository.h | 4 ++-- sql/event_queue.cc | 24 +++++++----------------- sql/event_queue.h | 2 +- sql/event_scheduler.cc | 16 ++++++++-------- sql/event_scheduler.h | 12 +++++++++--- sql/events.cc | 21 ++++++++++----------- sql/events.h | 5 ++++- 10 files changed, 65 insertions(+), 86 deletions(-) diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 67ba371772a..5196cae22e3 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -81,7 +81,7 @@ Event_queue_element_for_exec::~Event_queue_element_for_exec() RETURN VALUE Address or NULL in case of error - + NOTE Created on THD's mem_root */ @@ -174,7 +174,7 @@ Event_parse_data::init_body(THD *thd) while (body_begin < body_end) { - if ((*body_end == '\0') || + if ((*body_end == '\0') || (my_isspace(thd->variables.character_set_client, *body_end))) { /* consume NULs and meaningless whitespace */ --body.length; @@ -186,7 +186,7 @@ Event_parse_data::init_body(THD *thd) consume closing comments This is arguably wrong, but it's the best we have until the parser is - changed to be smarter. FIXME PARSER + changed to be smarter. FIXME PARSER See also the sp_head code, where something like this is done also. @@ -296,7 +296,7 @@ Event_parse_data::init_execute_at(THD *thd) if (item_execute_at->fix_fields(thd, &item_execute_at)) goto wrong_value; - + /* no starts and/or ends in case of execute_at */ DBUG_PRINT("info", ("starts_null && ends_null should be 1 is %d", (starts_null && ends_null))); @@ -702,7 +702,7 @@ Event_basic::load_string_fields(Field **fields, ...) ret= TRUE; break; } - field_value->length= strlen(field_value->str); + field_value->length= strlen(field_value->str); field_name= (enum enum_events_table_field) va_arg(args, int); } @@ -778,7 +778,7 @@ Event_timed::Event_timed(): */ Event_timed::~Event_timed() -{ +{ } @@ -1382,7 +1382,6 @@ Event_queue_element::compute_next_execution_time() DBUG_PRINT("info", ("Dropped: %d", dropped)); status= Event_queue_element::DISABLED; status_changed= TRUE; - dropped= TRUE; goto ret; } @@ -1574,7 +1573,7 @@ Event_queue_element::mark_last_executed(THD *thd) last_executed= (my_time_t) thd->query_start(); last_executed_changed= TRUE; - + execution_count++; } @@ -1762,7 +1761,7 @@ Event_timed::get_create_event(THD *thd, String *buf) */ int -Event_job_data::get_fake_create_event(THD *thd, String *buf) +Event_job_data::get_fake_create_event(String *buf) { DBUG_ENTER("Event_job_data::get_create_event"); /* FIXME: "EVERY 3337 HOUR" is asking for trouble. */ @@ -1853,7 +1852,7 @@ done: RETURN VALUE 0 success EVEX_COMPILE_ERROR error during compilation - EVEX_MICROSECOND_UNSUP mysql.event was tampered + EVEX_MICROSECOND_UNSUP mysql.event was tampered */ int @@ -1878,7 +1877,7 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root) show_create.length(0); - switch (get_fake_create_event(thd, &show_create)) { + switch (get_fake_create_event(&show_create)) { case EVEX_MICROSECOND_UNSUP: DBUG_RETURN(EVEX_MICROSECOND_UNSUP); case 0: @@ -2043,7 +2042,7 @@ event_change_security_context(THD *thd, LEX_STRING user, LEX_STRING host, thd->security_ctx= &thd->main_security_ctx; #endif DBUG_RETURN(FALSE); -} +} /* diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h index 8e013e40400..513f60df657 100644 --- a/sql/event_data_objects.h +++ b/sql/event_data_objects.h @@ -127,24 +127,6 @@ public: bool update_timing_fields(THD *thd); - - static void *operator new(size_t size) - { - void *p; - DBUG_ENTER("Event_queue_element::new(size)"); - p= my_malloc(size, MYF(0)); - DBUG_PRINT("info", ("alloc_ptr: 0x%lx", (long) p)); - DBUG_RETURN(p); - } - - static void operator delete(void *ptr, size_t size) - { - DBUG_ENTER("Event_queue_element::delete(ptr,size)"); - DBUG_PRINT("enter", ("free_ptr: 0x%lx", (long) ptr)); - TRASH(ptr, size); - my_free((gptr) ptr, MYF(0)); - DBUG_VOID_RETURN; - } }; @@ -206,7 +188,7 @@ public: compile(THD *thd, MEM_ROOT *mem_root); private: int - get_fake_create_event(THD *thd, String *buf); + get_fake_create_event(String *buf); Event_job_data(const Event_job_data &); /* Prevent use of these */ void operator=(Event_job_data &); diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 0c59d3e92f8..9e1ce1b4594 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -142,7 +142,7 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = EVEX_GENERAL_ERROR Bad data EVEX_GET_FIELD_FAILED Field count does not match. table corrupted? - DESCRIPTION + DESCRIPTION Used both when an event is created and when it is altered. */ @@ -178,7 +178,7 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et, /* Change the SQL_MODE only if body was present in an ALTER EVENT and of course always during CREATE EVENT. - */ + */ if (et->body.str) { fields[ET_FIELD_SQL_MODE]->store((longlong)thd->variables.sql_mode, TRUE); @@ -237,7 +237,7 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et, fields[ET_FIELD_TRANSIENT_INTERVAL]->set_null(); fields[ET_FIELD_STARTS]->set_null(); fields[ET_FIELD_ENDS]->set_null(); - + TIME time; my_tz_UTC->gmt_sec_to_TIME(&time, et->execute_at); @@ -253,7 +253,7 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et, this is an error if the action is create. something is borked */ } - + ((Field_timestamp *)fields[ET_FIELD_MODIFIED])->set_time(); if (et->comment.str) @@ -323,12 +323,12 @@ Event_db_repository::index_read_for_db_for_i_s(THD *thd, TABLE *schema_table, ret= copy_event_to_schema_table(thd, schema_table, event_table); if (ret == 0) ret= event_table->file->index_next_same(event_table->record[0], - key_buf, key_len); + key_buf, key_len); } while (ret == 0); } DBUG_PRINT("info", ("Scan finished. ret=%d", ret)); } - event_table->file->ha_index_end(); + event_table->file->ha_index_end(); /* ret is guaranteed to be != 0 */ if (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND) DBUG_RETURN(FALSE); @@ -489,7 +489,7 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type, check_parse_params() thd Thread context parse_data Event's data - + RETURN VALUE FALSE OK TRUE Error (reported) @@ -535,7 +535,7 @@ check_parse_params(THD *thd, Event_parse_data *parse_data) 0 OK EVEX_GENERAL_ERROR Failure - DESCRIPTION + DESCRIPTION Creates an event. Relies on mysql_event_fill_row which is shared with ::update_event. The name of the event is inside "et". */ @@ -630,7 +630,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data, handle it here */ if ((ret= mysql_event_fill_row(thd, table, parse_data, FALSE))) - goto err; + goto err; /* Close active transaction only if We are going to modify disk */ if (end_active_trans(thd)) @@ -647,7 +647,7 @@ ok: (void) mysql_change_db(thd, old_db.str, 1); /* This statement may cause a spooky valgrind warning at startup - inside init_key_cache on my system (ahristov, 2006/08/10) + inside init_key_cache on my system (ahristov, 2006/08/10) */ close_thread_tables(thd); DBUG_RETURN(FALSE); @@ -914,14 +914,14 @@ Event_db_repository::drop_schema_events(THD *thd, LEX_STRING schema) */ void -Event_db_repository::drop_events_by_field(THD *thd, +Event_db_repository::drop_events_by_field(THD *thd, enum enum_events_table_field field, LEX_STRING field_value) { int ret= 0; TABLE *table= NULL; READ_RECORD read_record_info; - DBUG_ENTER("Event_db_repository::drop_events_by_field"); + DBUG_ENTER("Event_db_repository::drop_events_by_field"); DBUG_PRINT("enter", ("field=%d field_value=%s", field, field_value.str)); if (open_event_table(thd, TL_WRITE, &table)) diff --git a/sql/event_db_repository.h b/sql/event_db_repository.h index 4991e2d0aa2..7d609dba860 100644 --- a/sql/event_db_repository.h +++ b/sql/event_db_repository.h @@ -62,7 +62,7 @@ public: update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname, LEX_STRING *new_name); - bool + bool drop_event(THD *thd, LEX_STRING db, LEX_STRING name, bool drop_if_exists); void @@ -98,5 +98,5 @@ private: Event_db_repository(const Event_db_repository &); void operator=(Event_db_repository &); }; - + #endif /* _EVENT_DB_REPOSITORY_H_ */ diff --git a/sql/event_queue.cc b/sql/event_queue.cc index ef9dddf9195..7832a0337e7 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -32,16 +32,6 @@ #define LOCK_QUEUE_DATA() lock_data(SCHED_FUNC, __LINE__) #define UNLOCK_QUEUE_DATA() unlock_data(SCHED_FUNC, __LINE__) -struct event_queue_param -{ - THD *thd; - Event_queue *queue; - pthread_mutex_t LOCK_loaded; - pthread_cond_t COND_loaded; - bool loading_finished; -}; - - /* Compares the execute_at members of two Event_queue_element instances. Used as callback for the prioritized queue when shifting @@ -62,7 +52,7 @@ struct event_queue_param execute_at.second_part is not considered during comparison */ -static int +static int event_queue_element_compare_q(void *vptr, byte* a, byte *b) { my_time_t lhs = ((Event_queue_element *)a)->execute_at; @@ -183,7 +173,7 @@ Event_queue::deinit_queue() } -/* +/** Adds an event to the queue. SYNOPSIS @@ -209,7 +199,7 @@ Event_queue::create_event(THD *thd, Event_queue_element *new_element) LOCK_QUEUE_DATA(); queue_insert_safe(&queue, (byte *) new_element); dbug_dump_queue(thd->query_start()); - pthread_cond_broadcast(&COND_queue_state); + pthread_cond_broadcast(&COND_queue_state); UNLOCK_QUEUE_DATA(); } DBUG_VOID_RETURN; @@ -256,7 +246,7 @@ Event_queue::update_event(THD *thd, LEX_STRING dbname, LEX_STRING name, { DBUG_PRINT("info", ("new event in the queue: 0x%lx", (long) new_element)); queue_insert_safe(&queue, (byte *) new_element); - pthread_cond_broadcast(&COND_queue_state); + pthread_cond_broadcast(&COND_queue_state); } dbug_dump_queue(thd->query_start()); @@ -287,7 +277,7 @@ Event_queue::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name) find_n_remove_event(dbname, name); dbug_dump_queue(thd->query_start()); UNLOCK_QUEUE_DATA(); - + /* We don't signal here because the scheduler will catch the change next time it wakes up. @@ -309,7 +299,7 @@ Event_queue::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name) RETURN VALUE >=0 Number of dropped events - + NOTE Expected is the caller to acquire lock on LOCK_event_queue */ @@ -341,7 +331,7 @@ Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern, i++; } /* - We don't call pthread_cond_broadcast(&COND_queue_state); + We don't call pthread_cond_broadcast(&COND_queue_state); If we remove the top event: 1. The queue is empty. The scheduler will wake up at some time and realize that the queue is empty. If create_event() comes inbetween diff --git a/sql/event_queue.h b/sql/event_queue.h index 338a6c8f903..95f52b7b588 100644 --- a/sql/event_queue.h +++ b/sql/event_queue.h @@ -34,7 +34,7 @@ public: bool init_queue(THD *thd); - + void deinit_queue(); diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 3c8ecf6ca3a..287bed27bd6 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -240,7 +240,7 @@ event_scheduler_thread(void *arg) /* - Function that executes an event in a child thread. Setups the + Function that executes an event in a child thread. Setups the environment for the event execution and cleans after that. SYNOPSIS @@ -254,7 +254,7 @@ event_scheduler_thread(void *arg) pthread_handler_t event_worker_thread(void *arg) { - THD *thd; + THD *thd; Event_queue_element_for_exec *event= (Event_queue_element_for_exec *)arg; thd= event->thd; @@ -267,7 +267,7 @@ event_worker_thread(void *arg) /* - Function that executes an event in a child thread. Setups the + Function that executes an event in a child thread. Setups the environment for the event execution and cleans after that. SYNOPSIS @@ -458,7 +458,7 @@ Event_scheduler::start() scheduler_thd= new_thd; DBUG_PRINT("info", ("Setting state go RUNNING")); state= RUNNING; - DBUG_PRINT("info", ("Forking new thread for scheduduler. THD: 0x%lx", (long) new_thd)); + DBUG_PRINT("info", ("Forking new thread for scheduler. THD: 0x%lx", (long) new_thd)); if (pthread_create(&th, &connection_attrib, event_scheduler_thread, (void*)scheduler_param_value)) { @@ -525,7 +525,7 @@ Event_scheduler::run(THD *thd) "event_name=0x%lx", (long) event_name)); if (event_name) { - if ((res= execute_top(thd, event_name))) + if ((res= execute_top(event_name))) break; } else @@ -559,7 +559,7 @@ Event_scheduler::run(THD *thd) */ bool -Event_scheduler::execute_top(THD *thd, Event_queue_element_for_exec *event_name) +Event_scheduler::execute_top(Event_queue_element_for_exec *event_name) { THD *new_thd; pthread_t th; @@ -631,7 +631,7 @@ Event_scheduler::is_running() } -/* +/** Stops the scheduler (again). Waits for acknowledgement from the scheduler that it has stopped - synchronous stopping. @@ -715,7 +715,7 @@ Event_scheduler::workers_count() { THD *tmp; uint count= 0; - + DBUG_ENTER("Event_scheduler::workers_count"); pthread_mutex_lock(&LOCK_thread_count); // For unlink from list I_List_iterator it(threads); diff --git a/sql/event_scheduler.h b/sql/event_scheduler.h index 2ab21464057..74d53c4f63d 100644 --- a/sql/event_scheduler.h +++ b/sql/event_scheduler.h @@ -15,6 +15,12 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* + This file is internal to Events module. Please do not include it directly. + All public declarations of Events module are in events.h and + event_data_objects.h. +*/ + class Event_queue; class Event_job_data; @@ -31,7 +37,7 @@ void deinit_event_thread(THD *thd); -class Event_worker_thread +class Event_worker_thread { public: static void @@ -74,7 +80,7 @@ public: bool run(THD *thd); - void + void init_scheduler(Event_queue *queue); void @@ -99,7 +105,7 @@ private: /* helper functions */ bool - execute_top(THD *thd, Event_queue_element_for_exec *event_name); + execute_top(Event_queue_element_for_exec *event_name); /* helper functions for working with mutexes & conditionals */ void diff --git a/sql/events.cc b/sql/events.cc index 88014ee34af..02e5a292e16 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -49,7 +49,7 @@ counterpart. 1. CREATE EVENT the_name ON SCHEDULE EVERY 1 SECOND DISABLE DO SELECT 1; 2. DROP EVENT the_name - + In other words, the first one will create a row in mysql.event . In the second step because there will be a line, disk based drop will pass and the scheduler will remove the memory counterpart. The reason is that @@ -309,7 +309,7 @@ Events::Events() TRUE Error (Reported) NOTES - In case there is an event with the same name (db) and + In case there is an event with the same name (db) and IF NOT EXISTS is specified, an warning is put into the stack. */ @@ -346,7 +346,6 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) pthread_mutex_unlock(&LOCK_event_metadata); DBUG_RETURN(ret); - } @@ -364,7 +363,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) TRUE Error NOTES - et contains data about dbname and event name. + et contains data about dbname and event name. new_name is the new name of the event, if not null this means that RENAME TO was specified in the query */ @@ -396,7 +395,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, sp_name *rename_to) new_element))) { DBUG_ASSERT(ret == OP_LOAD_ERROR); - delete new_element; + delete new_element; } else event_queue->update_event(thd, parse_data->dbname, parse_data->name, @@ -444,7 +443,7 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) } -/* +/** Drops all events from a schema SYNOPSIS @@ -457,8 +456,8 @@ void Events::drop_schema_events(THD *thd, char *db) { LEX_STRING const db_lex= { db, strlen(db) }; - - DBUG_ENTER("Events::drop_schema_events"); + + DBUG_ENTER("Events::drop_schema_events"); DBUG_PRINT("enter", ("dropping events from %s", db)); if (unlikely(check_system_tables_error)) { @@ -697,7 +696,7 @@ Events::deinit() } -/* +/** Inits Events mutexes SYNOPSIS @@ -755,7 +754,7 @@ Events::dump_internal_status() } -/* +/** Starts execution of events by the scheduler SYNOPSIS @@ -912,7 +911,7 @@ Events::check_system_tables(THD *thd) RETURN VALUE 0 OK - !0 Error (EVEX_OPEN_TABLE_FAILED, EVEX_MICROSECOND_UNSUP, + !0 Error (EVEX_OPEN_TABLE_FAILED, EVEX_MICROSECOND_UNSUP, EVEX_COMPILE_ERROR) - in all these cases mysql.event was tampered. diff --git a/sql/events.h b/sql/events.h index 35ee3c569d0..f97a0c5f57e 100644 --- a/sql/events.h +++ b/sql/events.h @@ -19,7 +19,6 @@ class sp_name; class Event_parse_data; class Event_db_repository; class Event_queue; -class Event_queue_element; class Event_scheduler; /* Return codes */ @@ -38,6 +37,10 @@ enum enum_events_error_code int sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs); +/** + @class Events -- a facade to the functionality of the Event Scheduler. + +*/ class Events { From 9b227f8f3ab2568e48de3e42964a2cc6f0b6e283 Mon Sep 17 00:00:00 2001 From: "kostja@bodhi.local" <> Date: Fri, 23 Mar 2007 18:19:53 +0300 Subject: [PATCH 04/14] Update an imperfect error message. --- sql/sql_servers.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 7b3b71cdd9a..60ca08fb555 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -208,7 +208,7 @@ my_bool servers_reload(THD *thd) if (simple_open_n_lock_tables(thd, tables)) { - sql_print_error("Fatal error: Can't open and lock privilege tables: %s", + sql_print_error("Can't open and lock privilege tables: %s", thd->net.last_error); goto end; } From bf6210bed5721385356f15ad4204819cfad1a73e Mon Sep 17 00:00:00 2001 From: "kostja@bodhi.local" <> Date: Fri, 23 Mar 2007 19:14:08 +0300 Subject: [PATCH 05/14] Change module prefix in error messages: SCHEDULER -> Event Scheduler, to not collide with the recently introduced thread scheduler module. --- mysql-test/r/events.result | 14 ++++++------- sql/event_data_objects.cc | 7 ++++--- sql/event_queue.cc | 7 ++++--- sql/event_scheduler.cc | 41 ++++++++++++++++++++++---------------- sql/events.cc | 25 ++++++++++++----------- sql/share/errmsg.txt | 6 +++--- 6 files changed, 55 insertions(+), 45 deletions(-) diff --git a/mysql-test/r/events.result b/mysql-test/r/events.result index cab5762012c..641de1571c3 100644 --- a/mysql-test/r/events.result +++ b/mysql-test/r/events.result @@ -229,10 +229,10 @@ Db Name Definer Time zone Type Execute at Interval value Interval field Starts E events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED ALTER TABLE mysql.event ADD dummy INT FIRST; SHOW EVENTS; -ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 18. Table probably corrupted +ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 18. The table is probably corrupted ALTER TABLE mysql.event DROP dummy, ADD dummy2 VARCHAR(64) FIRST; SHOW EVENTS; -ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 18. Table probably corrupted +ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 18. The table is probably corrupted ALTER TABLE mysql.event DROP dummy2; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status @@ -241,7 +241,7 @@ CREATE TABLE event_like LIKE mysql.event; INSERT INTO event_like SELECT * FROM mysql.event; ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default ''; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; -ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log. +ERROR HY000: Cannot load from mysql.event. The table is probably corrupted. Please see the error log for details ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default ''; SHOW CREATE TABLE mysql.event; Table Create Table @@ -266,7 +266,7 @@ event CREATE TABLE `event` ( PRIMARY KEY (`db`,`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Events' SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; -ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log. +ERROR HY000: Cannot load from mysql.event. The table is probably corrupted. Please see the error log for details ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin default ''; "This should work" SHOW EVENTS; @@ -274,13 +274,13 @@ Db Name Definer Time zone Type Execute at Interval value Interval field Starts E events_test intact_check root@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default ''; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; -ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log. +ERROR HY000: Cannot load from mysql.event. The table is probably corrupted. Please see the error log for details ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default ''; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; -ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log. +ERROR HY000: Cannot load from mysql.event. The table is probably corrupted. Please see the error log for details ALTER TABLE mysql.event DROP comment, DROP starts; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; -ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 15. Table probably corrupted +ERROR HY000: Column count of mysql.event is wrong. Expected 17, found 15. The table is probably corrupted DROP TABLE mysql.event; CREATE TABLE mysql.event like event_like; INSERT INTO mysql.event SELECT * FROM event_like; diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 5196cae22e3..c3ac488fb14 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -1926,9 +1926,10 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root) thd->is_fatal_error)); lex.unit.cleanup(); - sql_print_error("SCHEDULER: Error during compilation of %s.%s or " - "thd->is_fatal_error: %d", - dbname.str, name.str, thd->is_fatal_error); + sql_print_error("Event Scheduler: " + "%serror during compilation of %s.%s", + thd->is_fatal_error ? "fatal " : "", + dbname.str, name.str); ret= EVEX_COMPILE_ERROR; goto done; diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 7832a0337e7..f110bfdd1bf 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -138,7 +138,7 @@ Event_queue::init_queue(THD *thd) 0 /*max_on_top*/, event_queue_element_compare_q, NULL, EVENT_QUEUE_EXTENT)) { - sql_print_error("SCHEDULER: Can't initialize the execution queue"); + sql_print_error("Event Scheduler: Can't initialize the execution queue"); goto err; } @@ -453,7 +453,8 @@ Event_queue::empty_queue() uint i; DBUG_ENTER("Event_queue::empty_queue"); DBUG_PRINT("enter", ("Purging the queue. %u element(s)", queue.elements)); - sql_print_information("SCHEDULER: Purging queue. %u events", queue.elements); + sql_print_information("Event Scheduler: Purging the queue. %u events", + queue.elements); /* empty the queue */ for (i= 0; i < queue.elements; ++i) { @@ -586,7 +587,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd, if (top->status == Event_queue_element::DISABLED) { DBUG_PRINT("info", ("removing from the queue")); - sql_print_information("SCHEDULER: Last execution of %s.%s. %s", + sql_print_information("Event Scheduler: Last execution of %s.%s. %s", top->dbname.str, top->name.str, top->dropped? "Dropping.":""); delete top; diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 287bed27bd6..d50ea932596 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -78,7 +78,7 @@ Event_worker_thread::print_warnings(THD *thd, Event_job_data *et) char prefix_buf[5 * STRING_BUFFER_USUAL_SIZE]; String prefix(prefix_buf, sizeof(prefix_buf), system_charset_info); prefix.length(0); - prefix.append("SCHEDULER: ["); + prefix.append("Event Scheduler: ["); append_identifier(thd, &prefix, et->definer.str, et->definer.length); prefix.append("][", 2); @@ -304,7 +304,8 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) goto end; } - sql_print_information("SCHEDULER: [%s.%s of %s] executing in thread %lu. ", + sql_print_information("Event Scheduler: " + "[%s.%s of %s] executing in thread %lu. ", job_data->dbname.str, job_data->name.str, job_data->definer.str, thd->thread_id); @@ -314,23 +315,25 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) print_warnings(thd, job_data); - sql_print_information("SCHEDULER: [%s.%s of %s] executed in thread %lu. " + sql_print_information("Event Scheduler: " + "[%s.%s of %s] executed in thread %lu. " "RetCode=%d", job_data->dbname.str, job_data->name.str, job_data->definer.str, thd->thread_id, ret); if (ret == EVEX_COMPILE_ERROR) - sql_print_information("SCHEDULER: COMPILE ERROR for event %s.%s of %s", + sql_print_information("Event Scheduler: " + "COMPILE ERROR for event %s.%s of %s", job_data->dbname.str, job_data->name.str, job_data->definer.str); else if (ret == EVEX_MICROSECOND_UNSUP) - sql_print_information("SCHEDULER: MICROSECOND is not supported"); + sql_print_information("Event Scheduler: MICROSECOND is not supported"); end: delete job_data; if (event->dropped) { - sql_print_information("SCHEDULER: Dropping %s.%s", event->dbname.str, - event->name.str); + sql_print_information("Event Scheduler: Dropping %s.%s", + event->dbname.str, event->name.str); /* Using db_repository can lead to a race condition because we access the table without holding LOCK_metadata. @@ -442,7 +445,7 @@ Event_scheduler::start() if (!(new_thd= new THD)) { - sql_print_error("SCHEDULER: Cannot init manager event thread"); + sql_print_error("Event Scheduler: Cannot initialize the scheduler thread"); ret= TRUE; goto end; } @@ -501,7 +504,7 @@ Event_scheduler::run(THD *thd) int res= FALSE; DBUG_ENTER("Event_scheduler::run"); - sql_print_information("SCHEDULER: Manager thread started with id %lu", + sql_print_information("Event Scheduler: scheduler thread started with id %lu", thd->thread_id); /* Recalculate the values in the queue because there could have been stops @@ -516,7 +519,8 @@ Event_scheduler::run(THD *thd) /* Gets a minimized version */ if (queue->get_top_for_execution_if_time(thd, &event_name)) { - sql_print_information("SCHEDULER: Serious error during getting next " + sql_print_information("Event Scheduler: " + "Serious error during getting next " "event to execute. Stopping"); break; } @@ -540,7 +544,7 @@ Event_scheduler::run(THD *thd) state= INITIALIZED; pthread_cond_signal(&COND_state); UNLOCK_DATA(); - sql_print_information("SCHEDULER: Stopped"); + sql_print_information("Event Scheduler: Stopped"); DBUG_RETURN(res); } @@ -657,8 +661,8 @@ Event_scheduler::stop() /* Guarantee we don't catch spurious signals */ do { - DBUG_PRINT("info", ("Waiting for COND_started_or_stopped from the manager " - "thread. Current value of state is %s . " + DBUG_PRINT("info", ("Waiting for COND_started_or_stopped from " + "the scheduler thread. Current value of state is %s . " "workers count=%d", scheduler_states_names[state].str, workers_count())); /* @@ -672,20 +676,23 @@ Event_scheduler::stop() */ state= STOPPING; - DBUG_PRINT("info", ("Manager thread has id %lu", scheduler_thd->thread_id)); + DBUG_PRINT("info", ("Scheduler thread has id %lu", + scheduler_thd->thread_id)); /* Lock from delete */ pthread_mutex_lock(&scheduler_thd->LOCK_delete); /* This will wake up the thread if it waits on Queue's conditional */ - sql_print_information("SCHEDULER: Killing manager thread %lu", + sql_print_information("Event Scheduler: Killing the scheduler thread, " + "thread id %lu", scheduler_thd->thread_id); scheduler_thd->awake(THD::KILL_CONNECTION); pthread_mutex_unlock(&scheduler_thd->LOCK_delete); /* thd could be 0x0, when shutting down */ - sql_print_information("SCHEDULER: Waiting the manager thread to reply"); + sql_print_information("Event Scheduler: " + "Waiting for the scheduler thread to reply"); COND_STATE_WAIT(thd, NULL, "Waiting scheduler to stop"); } while (state == STOPPING); - DBUG_PRINT("info", ("Manager thread has cleaned up. Set state to INIT")); + DBUG_PRINT("info", ("Scheduler thread has cleaned up. Set state to INIT")); /* The rationale behind setting it to NULL here but not destructing it beforehand is because the THD will be deinited in event_scheduler_thread(). diff --git a/sql/events.cc b/sql/events.cc index 02e5a292e16..fd8160e103c 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -641,7 +641,7 @@ Events::init() if (check_system_tables(thd)) { check_system_tables_error= TRUE; - sql_print_error("SCHEDULER: The system tables are damaged. " + sql_print_error("Event Scheduler: The system tables are damaged. " "The scheduler subsystem will be unusable during this run."); goto end; } @@ -649,7 +649,7 @@ Events::init() if (event_queue->init_queue(thd) || load_events_from_db(thd)) { - sql_print_error("SCHEDULER: Error while loading from disk."); + sql_print_error("Event Scheduler: Error while loading from disk."); goto end; } @@ -862,7 +862,7 @@ Events::check_system_tables(THD *thd) if ((ret= simple_open_n_lock_tables(thd, &tables))) { - sql_print_error("SCHEDULER: Cannot open mysql.db"); + sql_print_error("Event Scheduler: Cannot open mysql.db"); ret= TRUE; } ret= table_check_intact(tables.table, MYSQL_DB_FIELD_COUNT, @@ -877,7 +877,7 @@ Events::check_system_tables(THD *thd) if (simple_open_n_lock_tables(thd, &tables)) { - sql_print_error("SCHEDULER: Cannot open mysql.user"); + sql_print_error("Event Scheduler: Cannot open mysql.user"); ret= TRUE; } else @@ -933,7 +933,7 @@ Events::load_events_from_db(THD *thd) if ((ret= db_repository->open_event_table(thd, TL_READ, &table))) { - sql_print_error("SCHEDULER: Table mysql.event is damaged. Can not open"); + sql_print_error("Event Scheduler: Table mysql.event is damaged. Can not open"); DBUG_RETURN(EVEX_OPEN_TABLE_FAILED); } @@ -950,8 +950,9 @@ Events::load_events_from_db(THD *thd) if ((ret= et->load_from_row(thd, table))) { - sql_print_error("SCHEDULER: Error while loading from mysql.event. " - "Table probably corrupted"); + sql_print_error("Event Scheduler: " + "Error while reading from mysql.event. " + "The table is probably corrupted"); break; } if (et->status != Event_queue_element::ENABLED) @@ -964,7 +965,7 @@ Events::load_events_from_db(THD *thd) /* let's find when to be executed */ if (et->compute_next_execution_time()) { - sql_print_error("SCHEDULER: Error while computing execution time of %s.%s." + sql_print_error("Event Scheduler: Error while computing execution time of %s.%s." " Skipping", et->dbname.str, et->name.str); continue; } @@ -981,11 +982,11 @@ Events::load_events_from_db(THD *thd) */ switch (ret= temp_job_data.compile(thd, thd->mem_root)) { case EVEX_MICROSECOND_UNSUP: - sql_print_error("SCHEDULER: mysql.event is tampered. MICROSECOND is not " + sql_print_error("Event Scheduler: mysql.event is tampered. MICROSECOND is not " "supported but found in mysql.event"); break; case EVEX_COMPILE_ERROR: - sql_print_error("SCHEDULER: Error while compiling %s.%s. Aborting load", + sql_print_error("Event Scheduler: Error while compiling %s.%s. Aborting load", et->dbname.str, et->name.str); break; default: @@ -1017,8 +1018,8 @@ end: else { ret= 0; - sql_print_information("SCHEDULER: Loaded %d event%s", count, - (count == 1)?"":"s"); + sql_print_information("Event Scheduler: Loaded %d event%s", + count, (count == 1)?"":"s"); } close_thread_tables(thd); diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 8159f014e93..c0da7053ac2 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5881,10 +5881,10 @@ ER_EVENT_NEITHER_M_EXPR_NOR_M_AT eng "No datetime expression provided" ger "Kein DATETIME-Ausdruck angegeben" ER_COL_COUNT_DOESNT_MATCH_CORRUPTED - eng "Column count of mysql.%s is wrong. Expected %d, found %d. Table probably corrupted" + eng "Column count of mysql.%s is wrong. Expected %d, found %d. The table is probably corrupted" ger "Spaltenanzahl von mysql.%s falsch. %d erwartet, aber %d gefunden. Tabelle ist wahrscheinlich beschdigt" ER_CANNOT_LOAD_FROM_TABLE - eng "Cannot load from mysql.%s. Table probably corrupted. See error log." + eng "Cannot load from mysql.%s. The table is probably corrupted. Please see the error log for details" ger "Kann mysql.%s nicht einlesen. Tabelle ist wahrscheinlich beschdigt, siehe Fehlerlog" ER_EVENT_CANNOT_DELETE eng "Failed to delete the event from mysql.event" @@ -5982,7 +5982,7 @@ ER_EVENT_RECURSIVITY_FORBIDDEN eng "Recursivity of EVENT DDL statements is forbidden when body is present" ger "Rekursivitt von EVENT-DDL-Anweisungen ist unzulssig wenn ein Hauptteil (Body) existiert" ER_EVENTS_DB_ERROR - eng "Cannot proceed because the tables used by events were found damaged at server start" + eng "Cannot proceed because system tables used by Event Scheduler were found damaged at server start" ger "Kann nicht weitermachen, weil die Tabellen, die von Events verwendet werden, beim Serverstart als beschdigt markiert wurden" ER_ONLY_INTEGERS_ALLOWED eng "Only integers allowed as number here" From 4b7fa1876d8f95f0b1ab7ee64454db56a8a6db25 Mon Sep 17 00:00:00 2001 From: "kostja@bodhi.local" <> Date: Sat, 24 Mar 2007 13:13:54 +0300 Subject: [PATCH 06/14] Remove files that were checked in by mistake. --- mysql-test/r/events_restart_phase0.result | 22 ---------------------- mysql-test/t/events_restart_phase0.log | 22 ---------------------- mysql-test/t/events_restart_phase0.result | 22 ---------------------- 3 files changed, 66 deletions(-) delete mode 100644 mysql-test/r/events_restart_phase0.result delete mode 100644 mysql-test/t/events_restart_phase0.log delete mode 100644 mysql-test/t/events_restart_phase0.result diff --git a/mysql-test/r/events_restart_phase0.result b/mysql-test/r/events_restart_phase0.result deleted file mode 100644 index 218b804a302..00000000000 --- a/mysql-test/r/events_restart_phase0.result +++ /dev/null @@ -1,22 +0,0 @@ -SHOW VARIABLES LIKE 'event%'; -Variable_name Value -event_scheduler DISABLED -SELECT @@global.event_scheduler; -@@global.event_scheduler -DISABLED -SET GLOBAL event_scheduler=on; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=off; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=0; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=1; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=2; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of '2' -SET GLOBAL event_scheduler=SUSPEND; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPEND' -SET GLOBAL event_scheduler=SUSPENDED; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPENDED' -SET GLOBAL event_scheduler=disabled; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'disabled' diff --git a/mysql-test/t/events_restart_phase0.log b/mysql-test/t/events_restart_phase0.log deleted file mode 100644 index 218b804a302..00000000000 --- a/mysql-test/t/events_restart_phase0.log +++ /dev/null @@ -1,22 +0,0 @@ -SHOW VARIABLES LIKE 'event%'; -Variable_name Value -event_scheduler DISABLED -SELECT @@global.event_scheduler; -@@global.event_scheduler -DISABLED -SET GLOBAL event_scheduler=on; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=off; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=0; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=1; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=2; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of '2' -SET GLOBAL event_scheduler=SUSPEND; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPEND' -SET GLOBAL event_scheduler=SUSPENDED; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPENDED' -SET GLOBAL event_scheduler=disabled; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'disabled' diff --git a/mysql-test/t/events_restart_phase0.result b/mysql-test/t/events_restart_phase0.result deleted file mode 100644 index 218b804a302..00000000000 --- a/mysql-test/t/events_restart_phase0.result +++ /dev/null @@ -1,22 +0,0 @@ -SHOW VARIABLES LIKE 'event%'; -Variable_name Value -event_scheduler DISABLED -SELECT @@global.event_scheduler; -@@global.event_scheduler -DISABLED -SET GLOBAL event_scheduler=on; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=off; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=0; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=1; -ERROR HY000: The MySQL server is running with the --event-scheduler=DISABLED option so it cannot execute this statement -SET GLOBAL event_scheduler=2; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of '2' -SET GLOBAL event_scheduler=SUSPEND; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPEND' -SET GLOBAL event_scheduler=SUSPENDED; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'SUSPENDED' -SET GLOBAL event_scheduler=disabled; -ERROR 42000: Variable 'event_scheduler' can't be set to the value of 'disabled' From 1381b26e3606d1c49939572d64dc654d74f5ae5f Mon Sep 17 00:00:00 2001 From: "thek@kpdesk.mysql.com" <> Date: Tue, 27 Mar 2007 18:05:17 +0200 Subject: [PATCH 07/14] Corrected error in test case: - 1.84e+15 converted to unsigned bigint should be 18400000000000000000 < 18446744073709551615. - The test will still fail on windows, and is extracted into a new bug report. --- mysql-test/r/sp.result | 3 --- mysql-test/t/sp.test | 1 - 2 files changed, 4 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index a30584b3ef2..c75697b93a2 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6018,9 +6018,6 @@ upper bounds unsigned bigint + 1 select bug20777(-1) as 'lower bounds unsigned bigint - 1'; lower bounds unsigned bigint - 1 0 -select bug20777(1.84e+19) as 'submitter value, 1.84e19'; -submitter value, 1.84e19 -9223372036854775808 create table examplebug20777 as select 0 as 'i', bug20777(9223372036854775806) as '2**63-2', diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index ca506104ab7..8403c8589ef 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -6955,7 +6955,6 @@ select bug20777(0) as 'lower bounds unsigned bigint'; select bug20777(18446744073709551615) as 'upper bounds unsigned bigint'; select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1'; select bug20777(-1) as 'lower bounds unsigned bigint - 1'; -select bug20777(1.84e+19) as 'submitter value, 1.84e19'; create table examplebug20777 as select 0 as 'i', From e56c6d2f25592af24d1f222f822f5b9899221558 Mon Sep 17 00:00:00 2001 From: "kostja@bodhi.local" <> Date: Tue, 27 Mar 2007 20:27:58 +0400 Subject: [PATCH 08/14] Change find_type family to accept const TYPELIB*. --- include/mysql_h.ic | 2 +- include/typelib.h | 3 ++- mysys/typelib.c | 2 +- sql/mysql_priv.h | 6 ++++-- sql/strfunc.cc | 6 ++++-- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/mysql_h.ic b/include/mysql_h.ic index 44c51b34c1d..7d16a886fd8 100644 --- a/include/mysql_h.ic +++ b/include/mysql_h.ic @@ -638,7 +638,7 @@ extern TYPELIB * copy_typelib(MEM_ROOT * root, TYPELIB * from); # 415 "mysql_com.h" extern void create_random_string(char * to, unsigned int, struct rand_struct * rand_st); # 30 "typelib.h" -extern int find_type(char * x, TYPELIB * typelib, unsigned int); +extern int find_type(char * x, const TYPELIB * typelib, unsigned int); # 429 "mysql_com.h" extern void get_salt_from_password(unsigned char * res, char const * password); # 422 "mysql_com.h" diff --git a/include/typelib.h b/include/typelib.h index 75d170e59d3..79d3acd2d64 100644 --- a/include/typelib.h +++ b/include/typelib.h @@ -26,7 +26,8 @@ typedef struct st_typelib { /* Different types saved here */ unsigned int *type_lengths; } TYPELIB; -extern int find_type(char *x,TYPELIB *typelib,unsigned int full_name); +extern int find_type(const char *x, const TYPELIB *typelib, + unsigned int full_name); extern void make_type(char *to,unsigned int nr,TYPELIB *typelib); extern const char *get_type(TYPELIB *typelib,unsigned int nr); extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from); diff --git a/mysys/typelib.c b/mysys/typelib.c index 4fab6f20493..97b03b72b24 100644 --- a/mysys/typelib.c +++ b/mysys/typelib.c @@ -42,7 +42,7 @@ >0 Offset+1 in typelib for matched string */ -int find_type(my_string x, TYPELIB *typelib, uint full_name) +int find_type(const char *x, const TYPELIB *typelib, uint full_name) { int find,pos,findpos; reg1 my_string i; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 608fb697d4f..81c82cf3ac8 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1561,8 +1561,10 @@ extern bool check_reserved_words(LEX_STRING *name); /* strfunc.cc */ ulonglong find_set(TYPELIB *lib, const char *x, uint length, CHARSET_INFO *cs, char **err_pos, uint *err_len, bool *set_warning); -uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match); -uint find_type2(TYPELIB *lib, const char *find, uint length, CHARSET_INFO *cs); +uint find_type(const TYPELIB *lib, const char *find, uint length, + bool part_match); +uint find_type2(const TYPELIB *lib, const char *find, uint length, + CHARSET_INFO *cs); void unhex_type2(TYPELIB *lib); uint check_word(TYPELIB *lib, const char *val, const char *end, const char **end_of_word); diff --git a/sql/strfunc.cc b/sql/strfunc.cc index 71b52a5145d..9ffc5fd127f 100644 --- a/sql/strfunc.cc +++ b/sql/strfunc.cc @@ -104,7 +104,8 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs, > 0 position in TYPELIB->type_names +1 */ -uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match) +uint find_type(const TYPELIB *lib, const char *find, uint length, + bool part_match) { uint found_count=0, found_pos=0; const char *end= find+length; @@ -144,7 +145,8 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match) >0 Offset+1 in typelib for matched string */ -uint find_type2(TYPELIB *typelib, const char *x, uint length, CHARSET_INFO *cs) +uint find_type2(const TYPELIB *typelib, const char *x, uint length, + CHARSET_INFO *cs) { int pos; const char *j; From 87f331b5ec85531ef1c5c228ec8850118225940e Mon Sep 17 00:00:00 2001 From: "thek@kpdesk.mysql.com" <> Date: Tue, 27 Mar 2007 18:46:53 +0200 Subject: [PATCH 09/14] manual merge --- mysql-test/r/sp.result | 3 --- 1 file changed, 3 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 954249a99ce..04e1be9f9f7 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6110,9 +6110,6 @@ upper bounds unsigned bigint + 1 select bug20777(-1) as 'lower bounds unsigned bigint - 1'; lower bounds unsigned bigint - 1 0 -select bug20777(1.84e+19) as 'submitter value, 1.84e19'; -submitter value, 1.84e19 -9223372036854775808 create table examplebug20777 as select 0 as 'i', bug20777(9223372036854775806) as '2**63-2', From b42b41640067e07fe8d22e67897e4f1a000291c2 Mon Sep 17 00:00:00 2001 From: "kostja@bodhi.local" <> Date: Tue, 27 Mar 2007 21:09:56 +0400 Subject: [PATCH 10/14] Remove unnecessary casts to uchar. The casts are stemming from the lexer API which internally uses unsigned char variables to address its state map. The implementation of the lexer should be internal to the lexer, and not influence the rest of the code. --- sql/event_data_objects.cc | 4 +-- sql/event_data_objects.h | 2 +- sql/ha_ndbcluster.cc | 2 +- sql/mysql_priv.h | 2 +- sql/partition_info.h | 2 +- sql/sp.cc | 2 +- sql/sp_head.cc | 9 +++---- sql/sp_head.h | 4 +-- sql/sql_lex.cc | 56 ++++++++++++++++----------------------- sql/sql_lex.h | 18 ++++++------- sql/sql_parse.cc | 8 +++--- sql/sql_partition.cc | 6 ++--- sql/sql_partition.h | 4 +-- sql/sql_prepare.cc | 2 +- sql/sql_trigger.cc | 2 +- sql/sql_view.cc | 10 +++---- sql/sql_yacc.yy | 16 +++++------ sql/table.cc | 6 ++--- sql/table.h | 4 +-- 19 files changed, 73 insertions(+), 86 deletions(-) diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index c3ac488fb14..e87a78a5e37 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -168,7 +168,7 @@ Event_parse_data::init_body(THD *thd) (long) body_begin, (long) thd->lex->ptr)); body.length= thd->lex->ptr - body_begin; - const uchar *body_end= body_begin + body.length - 1; + const char *body_end= body_begin + body.length - 1; /* Trim nuls or close-comments ('*'+'/') or spaces at the end */ while (body_begin < body_end) @@ -1919,7 +1919,7 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root) event_change_security_context(thd, definer_user, definer_host, dbname, &save_ctx); thd->lex= &lex; - mysql_init_query(thd, (uchar*) thd->query, thd->query_length); + mysql_init_query(thd, thd->query, thd->query_length); if (MYSQLparse((void *)thd) || thd->is_fatal_error) { DBUG_PRINT("error", ("error during compile or thd->is_fatal_error: %d", diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h index 513f60df657..358373889e5 100644 --- a/sql/event_data_objects.h +++ b/sql/event_data_objects.h @@ -217,7 +217,7 @@ public: */ bool do_not_create; - const uchar *body_begin; + const char *body_begin; LEX_STRING dbname; LEX_STRING name; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index bc1c3c8e324..bef58339e5b 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -6339,7 +6339,7 @@ int ndb_create_table_from_engine(THD *thd, const char *db, LEX *old_lex= thd->lex, newlex; thd->lex= &newlex; newlex.current_select= NULL; - lex_start(thd, (const uchar*) "", 0); + lex_start(thd, "", 0); int res= ha_create_table_from_engine(thd, db, table_name); thd->lex= old_lex; return res; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 81c82cf3ac8..f807dcdf21a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -841,7 +841,7 @@ bool is_update_query(enum enum_sql_command command); bool alloc_query(THD *thd, const char *packet, uint packet_length); void mysql_init_select(LEX *lex); void mysql_reset_thd_for_next_command(THD *thd); -void mysql_init_query(THD *thd, uchar *buf, uint length); +void mysql_init_query(THD *thd, const char *buf, uint length); bool mysql_new_select(LEX *lex, bool move_down); void create_select_for_variable(const char *var_name); void mysql_init_multi_delete(LEX *lex); diff --git a/sql/partition_info.h b/sql/partition_info.h index 8bcc769054f..6c21002c184 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -156,7 +156,7 @@ public: char *part_func_string; char *subpart_func_string; - uchar *part_state; + const char *part_state; partition_element *curr_part_elem; partition_element *current_partition; diff --git a/sql/sp.cc b/sql/sp.cc index c1a9aac0c24..d8dd9b3d67e 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -384,7 +384,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, if ((ret= sp_use_new_db(thd, name->m_db, &old_db, 1, &dbchanged))) goto end; - lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length()); + lex_start(thd, defstr.c_ptr(), defstr.length()); thd->spcont= 0; if (MYSQLparse(thd) || thd->is_fatal_error || newlex.sphead == NULL) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index f5e32847fb0..8eeec741dcf 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -541,15 +541,14 @@ void sp_head::init_strings(THD *thd, LEX *lex) { DBUG_ENTER("sp_head::init_strings"); - const uchar *endp; /* Used to trim the end */ + const char *endp; /* Used to trim the end */ /* During parsing, we must use thd->mem_root */ MEM_ROOT *root= thd->mem_root; if (m_param_begin && m_param_end) { m_params.length= m_param_end - m_param_begin; - m_params.str= strmake_root(root, - (char *)m_param_begin, m_params.length); + m_params.str= strmake_root(root, m_param_begin, m_params.length); } /* If ptr has overrun end_of_query then end_of_query is the end */ @@ -561,9 +560,9 @@ sp_head::init_strings(THD *thd, LEX *lex) endp= skip_rear_comments(m_body_begin, endp); m_body.length= endp - m_body_begin; - m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length); + m_body.str= strmake_root(root, m_body_begin, m_body.length); m_defstr.length= endp - lex->buf; - m_defstr.str= strmake_root(root, (char *)lex->buf, m_defstr.length); + m_defstr.str= strmake_root(root, lex->buf, m_defstr.length); DBUG_VOID_RETURN; } diff --git a/sql/sp_head.h b/sql/sp_head.h index 19dc2dac476..9aee9e9389e 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -126,7 +126,7 @@ public: create_field m_return_field_def; /* This is used for FUNCTIONs only. */ - const uchar *m_tmp_query; // Temporary pointer to sub query string + const char *m_tmp_query; // Temporary pointer to sub query string st_sp_chistics *m_chistics; ulong m_sql_mode; // For SHOW CREATE and execution LEX_STRING m_qname; // db.name @@ -174,7 +174,7 @@ public: */ HASH m_sroutines; // Pointers set during parsing - const uchar *m_param_begin, *m_param_end, *m_body_begin; + const char *m_param_begin, *m_param_end, *m_body_begin; /* Security context for stored routine which should be run under diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ad54289a9cc..26955c18342 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -33,10 +33,10 @@ sys_var *trg_new_row_fake_var= (sys_var*) 0x01; /* Macros to look like lex */ -#define yyGet() *(lex->ptr++) -#define yyGetLast() lex->ptr[-1] -#define yyPeek() lex->ptr[0] -#define yyPeek2() lex->ptr[1] +#define yyGet() ((uchar) *(lex->ptr++)) +#define yyGetLast() ((uchar) lex->ptr[-1]) +#define yyPeek() ((uchar) lex->ptr[0]) +#define yyPeek2() ((uchar) lex->ptr[1]) #define yyUnget() lex->ptr-- #define yySkip() lex->ptr++ #define yyLength() ((uint) (lex->ptr - lex->tok_start)-1) @@ -127,7 +127,7 @@ st_parsing_options::reset() (We already do too much here) */ -void lex_start(THD *thd, const uchar *buf, uint length) +void lex_start(THD *thd, const char *buf, uint length) { LEX *lex= thd->lex; DBUG_ENTER("lex_start"); @@ -238,9 +238,9 @@ void lex_end(LEX *lex) static int find_keyword(LEX *lex, uint len, bool function) { - const uchar *tok=lex->tok_start; + const char *tok= lex->tok_start; - SYMBOL *symbol= get_hash_symbol((const char *)tok,len,function); + SYMBOL *symbol= get_hash_symbol(tok, len, function); if (symbol) { lex->yylval->symbol.symbol=symbol; @@ -305,16 +305,16 @@ static LEX_STRING get_token(LEX *lex,uint length) static LEX_STRING get_quoted_token(LEX *lex,uint length, char quote) { LEX_STRING tmp; - const uchar *from, *end; - uchar *to; + const char *from, *end; + char *to; yyUnget(); // ptr points now after last token char tmp.length=lex->yytoklen=length; tmp.str=(char*) lex->thd->alloc(tmp.length+1); - for (from= lex->tok_start, to= (uchar*) tmp.str, end= to+length ; + for (from= lex->tok_start, to= tmp.str, end= to+length ; to != end ; ) { - if ((*to++= *from++) == (uchar) quote) + if ((*to++= *from++) == quote) from++; // Skip double quotes } *to= 0; // End null for safety @@ -341,9 +341,7 @@ static char *get_text(LEX *lex) { int l; if (use_mb(cs) && - (l = my_ismbchar(cs, - (const char *)lex->ptr-1, - (const char *)lex->end_of_query))) { + (l = my_ismbchar(cs, lex->ptr-1, lex->end_of_query))) { lex->ptr += l-1; continue; } @@ -368,12 +366,12 @@ static char *get_text(LEX *lex) yyUnget(); /* Found end. Unescape and return string */ - const uchar *str, *end; - uchar *start; + const char *str, *end; + char *start; str=lex->tok_start+1; end=lex->ptr-1; - if (!(start=(uchar*) lex->thd->alloc((uint) (end-str)+1))) + if (!(start= (char*) lex->thd->alloc((uint) (end-str)+1))) return (char*) ""; // Sql_alloc has set error flag if (!found_escape) { @@ -383,15 +381,14 @@ static char *get_text(LEX *lex) } else { - uchar *to; + char *to; for (to=start ; str != end ; str++) { #ifdef USE_MB int l; if (use_mb(cs) && - (l = my_ismbchar(cs, - (const char *)str, (const char *)end))) { + (l = my_ismbchar(cs, str, end))) { while (l--) *to++ = *str++; str--; @@ -437,7 +434,7 @@ static char *get_text(LEX *lex) *to=0; lex->yytoklen=(uint) (to-start); } - return (char*) start; + return start; } } return 0; // unexpected end of query @@ -556,7 +553,6 @@ int MYSQLlex(void *arg, void *yythd) lex->yylval=yylval; // The global state - lex->tok_end_prev= lex->tok_end; lex->tok_start_prev= lex->tok_start; lex->tok_start=lex->tok_end=lex->ptr; @@ -640,16 +636,14 @@ int MYSQLlex(void *arg, void *yythd) break; } case MY_LEX_IDENT: - const uchar *start; + const char *start; #if defined(USE_MB) && defined(USE_MB_IDENT) if (use_mb(cs)) { result_state= IDENT_QUOTED; if (my_mbcharlen(cs, yyGetLast()) > 1) { - int l = my_ismbchar(cs, - (const char *)lex->ptr-1, - (const char *)lex->end_of_query); + int l = my_ismbchar(cs, lex->ptr-1, lex->end_of_query); if (l == 0) { state = MY_LEX_CHAR; continue; @@ -661,9 +655,7 @@ int MYSQLlex(void *arg, void *yythd) if (my_mbcharlen(cs, c) > 1) { int l; - if ((l = my_ismbchar(cs, - (const char *)lex->ptr-1, - (const char *)lex->end_of_query)) == 0) + if ((l = my_ismbchar(cs, lex->ptr-1, lex->end_of_query)) == 0) break; lex->ptr += l-1; } @@ -786,9 +778,7 @@ int MYSQLlex(void *arg, void *yythd) if (my_mbcharlen(cs, c) > 1) { int l; - if ((l = my_ismbchar(cs, - (const char *)lex->ptr-1, - (const char *)lex->end_of_query)) == 0) + if ((l = my_ismbchar(cs, lex->ptr-1, lex->end_of_query)) == 0) break; lex->ptr += l-1; } @@ -1122,7 +1112,7 @@ int MYSQLlex(void *arg, void *yythd) Pointer to the last non-comment symbol of the statement. */ -const uchar *skip_rear_comments(const uchar *begin, const uchar *end) +const char *skip_rear_comments(const char *begin, const char *end) { while (begin < end && (end[-1] <= ' ' || end[-1] == '*' || end[-1] == '/' || end[-1] == ';')) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 13786606412..d8a5a0b04f0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -542,7 +542,7 @@ public: void set_limit(st_select_lex *values); void set_thd(THD *thd_arg) { thd= thd_arg; } - friend void lex_start(THD *thd, const uchar *buf, uint length); + friend void lex_start(THD *thd, const char *buf, uint length); friend int subselect_union_engine::exec(); List *get_unit_column_types(); @@ -743,7 +743,7 @@ public: void cut_subtree() { slave= 0; } bool test_limit(); - friend void lex_start(THD *thd, const uchar *buf, uint length); + friend void lex_start(THD *thd, const char *buf, uint length); st_select_lex() : n_sum_items(0), n_child_sum_items(0) {} void make_empty_select() { @@ -996,11 +996,11 @@ typedef struct st_lex : public Query_tables_list SELECT_LEX *current_select; /* list of all SELECT_LEX */ SELECT_LEX *all_selects_list; - const uchar *buf; /* The beginning of string, used by SPs */ - const uchar *ptr,*tok_start,*tok_end,*end_of_query; + const char *buf; /* The beginning of string, used by SPs */ + const char *ptr,*tok_start,*tok_end,*end_of_query; - /* The values of tok_start/tok_end as they were one call of MYSQLlex before */ - const uchar *tok_start_prev, *tok_end_prev; + /* The value of tok_start as they were one call of MYSQLlex before */ + const char *tok_start_prev; char *length,*dec,*change; LEX_STRING name; @@ -1202,7 +1202,7 @@ typedef struct st_lex : public Query_tables_list Pointers to part of LOAD DATA statement that should be rewritten during replication ("LOCAL 'filename' REPLACE INTO" part). */ - const uchar *fname_start, *fname_end; + const char *fname_start, *fname_end; /* Reference to a struct that contains information in various commands @@ -1319,10 +1319,10 @@ struct st_lex_local: public st_lex extern void lex_init(void); extern void lex_free(void); -extern void lex_start(THD *thd, const uchar *buf, uint length); +extern void lex_start(THD *thd, const char *buf, uint length); extern void lex_end(LEX *lex); extern int MYSQLlex(void *arg, void *yythd); -extern const uchar *skip_rear_comments(const uchar *ubegin, const uchar *uend); +extern const char *skip_rear_comments(const char *ubegin, const char *uend); extern bool is_lex_native_function(const LEX_STRING *name); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4c85ba252e5..7720f293b10 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -983,7 +983,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; /* init structures for VIEW processing */ table_list.select_lex= &(thd->lex->select_lex); - mysql_init_query(thd, (uchar*)"", 0); + mysql_init_query(thd, "", 0); thd->lex-> select_lex.table_list.link_in_list((byte*) &table_list, (byte**) &table_list.next_local); @@ -4970,7 +4970,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize) ****************************************************************************/ void -mysql_init_query(THD *thd, uchar *buf, uint length) +mysql_init_query(THD *thd, const char *buf, uint length) { DBUG_ENTER("mysql_init_query"); lex_start(thd, buf, length); @@ -5193,7 +5193,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length) DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on();); - mysql_init_query(thd, (uchar*) inBuf, length); + mysql_init_query(thd, inBuf, length); if (query_cache_send_result_to_client(thd, inBuf, length) <= 0) { LEX *lex= thd->lex; @@ -5272,7 +5272,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) bool error= 0; DBUG_ENTER("mysql_test_parse_for_slave"); - mysql_init_query(thd, (uchar*) inBuf, length); + mysql_init_query(thd, inBuf, length); if (!MYSQLparse((void*) thd) && ! thd->is_fatal_error && all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first)) error= 1; /* Ignore question */ diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index dbac53ed5f6..65a10a2120c 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -3700,9 +3700,9 @@ void get_partition_set(const TABLE *table, byte *buf, const uint index, possible to retrace this given an item tree. */ -bool mysql_unpack_partition(THD *thd, const uchar *part_buf, - uint part_info_len, - uchar *part_state, uint part_state_len, +bool mysql_unpack_partition(THD *thd, + const char *part_buf, uint part_info_len, + const char *part_state, uint part_state_len, TABLE* table, bool is_create_table_ind, handlerton *default_db_type) { diff --git a/sql/sql_partition.h b/sql/sql_partition.h index 7ed43527688..e0c0f1c5bd3 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -77,9 +77,9 @@ void get_full_part_id_from_key(const TABLE *table, byte *buf, KEY *key_info, const key_range *key_spec, part_id_range *part_spec); -bool mysql_unpack_partition(THD *thd, const uchar *part_buf, +bool mysql_unpack_partition(THD *thd, const char *part_buf, uint part_info_len, - uchar *part_state, uint part_state_len, + const char *part_state, uint part_state_len, TABLE *table, bool is_create_table_ind, handlerton *default_db_type); void make_used_partitions_str(partition_info *part_info, String *parts_str); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 37a6f68cfe8..e97670ab2b1 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2850,7 +2850,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) old_stmt_arena= thd->stmt_arena; thd->stmt_arena= this; - lex_start(thd, (uchar*) thd->query, thd->query_length); + lex_start(thd, thd->query, thd->query_length); lex->stmt_prepare_mode= TRUE; error= MYSQLparse((void *)thd) || thd->is_fatal_error || diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 311bd089c64..66132efb8e4 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -976,7 +976,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, LEX_STRING *trg_definer= it_definer++; thd->variables.sql_mode= (ulong)*trg_sql_mode; - lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length); + lex_start(thd, trg_create_str->str, trg_create_str->length); thd->spcont= 0; if (MYSQLparse((void *)thd) || thd->is_fatal_error) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index b619e451b22..b0c9de1453c 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -675,7 +675,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, char md5[MD5_BUFF_LENGTH]; bool can_be_merged; char dir_buff[FN_REFLEN], path_buff[FN_REFLEN]; - const uchar *endp; + const char *endp; LEX_STRING dir, file, path; DBUG_ENTER("mysql_register_view"); @@ -759,9 +759,9 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->query.str= (char*)str.ptr(); view->query.length= str.length()-1; // we do not need last \0 view->source.str= thd->query + thd->lex->create_view_select_start; - endp= (uchar*) view->source.str; - endp= skip_rear_comments(endp, (uchar*) (thd->query + thd->query_length)); - view->source.length= endp - (uchar*) view->source.str; + endp= view->source.str; + endp= skip_rear_comments(endp, thd->query + thd->query_length); + view->source.length= endp - view->source.str; view->file_version= 1; view->calc_md5(md5); view->md5.str= md5; @@ -970,7 +970,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, now Lex placed in statement memory */ table->view= lex= thd->lex= (LEX*) new(thd->mem_root) st_lex_local; - lex_start(thd, (uchar*)table->query.str, table->query.length); + lex_start(thd, table->query.str, table->query.length); view_select= &lex->select_lex; view_select->select_number= ++thd->select_number; { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 963146f3cb4..9d4c62052dd 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2695,7 +2695,7 @@ sp_proc_stmt_statement: else i->m_query.length= lex->tok_end - sp->m_tmp_query; i->m_query.str= strmake_root(YYTHD->mem_root, - (char *)sp->m_tmp_query, + sp->m_tmp_query, i->m_query.length); sp->add_instr(i); } @@ -9299,7 +9299,7 @@ param_marker: my_error(ER_VIEW_SELECT_VARIABLE, MYF(0)); MYSQL_YYABORT; } - item= new Item_param((uint) (lex->tok_start - (uchar *) thd->query)); + item= new Item_param((uint) (lex->tok_start - thd->query)); if (!($$= item) || lex->param_list.push_back(item)) { my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); @@ -10135,7 +10135,7 @@ option_type_value: if (!(qbuff.str= alloc_root(YYTHD->mem_root, qbuff.length + 5))) MYSQL_YYABORT; - strmake(strmake(qbuff.str, "SET ", 4), (char *)sp->m_tmp_query, + strmake(strmake(qbuff.str, "SET ", 4), sp->m_tmp_query, qbuff.length); qbuff.length+= 4; i->m_query= qbuff; @@ -11354,18 +11354,16 @@ view_select_aux: { THD *thd= YYTHD; LEX *lex= thd->lex; - char *stmt_beg= (lex->sphead ? - (char *)lex->sphead->m_tmp_query : - thd->query); + const char *stmt_beg= (lex->sphead ? + lex->sphead->m_tmp_query : thd->query); lex->create_view_select_start= $2 - stmt_beg; } | '(' remember_name select_paren ')' union_opt { THD *thd= YYTHD; LEX *lex= thd->lex; - char *stmt_beg= (lex->sphead ? - (char *)lex->sphead->m_tmp_query : - thd->query); + const char *stmt_beg= (lex->sphead ? + lex->sphead->m_tmp_query : thd->query); lex->create_view_select_start= $2 - stmt_beg; } ; diff --git a/sql/table.cc b/sql/table.cc index 4123473cf1e..71e510bf0ac 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -682,8 +682,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if ((share->partition_info_len= partition_info_len)) { if (!(share->partition_info= - (uchar*) memdup_root(&share->mem_root, next_chunk + 4, - partition_info_len + 1))) + memdup_root(&share->mem_root, next_chunk + 4, + partition_info_len + 1))) { my_free(buff, MYF(0)); goto err; @@ -1528,7 +1528,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, tmp= mysql_unpack_partition(thd, share->partition_info, share->partition_info_len, - (uchar*)share->part_state, + share->part_state, share->part_state_len, outparam, is_create_table, share->default_part_db_type); diff --git a/sql/table.h b/sql/table.h index aa053f207b3..0eb372e9cca 100644 --- a/sql/table.h +++ b/sql/table.h @@ -236,9 +236,9 @@ typedef struct st_table_share bool log_table; #ifdef WITH_PARTITION_STORAGE_ENGINE bool auto_partitioned; - const uchar *partition_info; + const char *partition_info; uint partition_info_len; - const uchar *part_state; + const char *part_state; uint part_state_len; handlerton *default_part_db_type; #endif From e5d6b0afd223b21ae5f52efd67b64ff3884a2862 Mon Sep 17 00:00:00 2001 From: "kostja@bodhi.local" <> Date: Tue, 27 Mar 2007 21:57:33 +0400 Subject: [PATCH 11/14] Fix warnings. --- include/typelib.h | 2 +- mysys/typelib.c | 2 +- sql/item_func.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/typelib.h b/include/typelib.h index 79d3acd2d64..e04ec20f2bc 100644 --- a/include/typelib.h +++ b/include/typelib.h @@ -26,7 +26,7 @@ typedef struct st_typelib { /* Different types saved here */ unsigned int *type_lengths; } TYPELIB; -extern int find_type(const char *x, const TYPELIB *typelib, +extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name); extern void make_type(char *to,unsigned int nr,TYPELIB *typelib); extern const char *get_type(TYPELIB *typelib,unsigned int nr); diff --git a/mysys/typelib.c b/mysys/typelib.c index 97b03b72b24..dc9f0850bbc 100644 --- a/mysys/typelib.c +++ b/mysys/typelib.c @@ -42,7 +42,7 @@ >0 Offset+1 in typelib for matched string */ -int find_type(const char *x, const TYPELIB *typelib, uint full_name) +int find_type(char *x, const TYPELIB *typelib, uint full_name) { int find,pos,findpos; reg1 my_string i; diff --git a/sql/item_func.cc b/sql/item_func.cc index cf3a4d3d758..59894c981af 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5069,7 +5069,7 @@ Item_func_sp::init_result_field(THD *thd) { DBUG_ENTER("Item_func_sp::init_result_field"); - LEX_STRING empty_name= { STRING_WITH_LEN("") }; + LEX_STRING empty_name= { C_STRING_WITH_LEN("") }; TABLE_SHARE *share; From c392623bf9fd24193673737902c9751a0bea3e3b Mon Sep 17 00:00:00 2001 From: "kostja@bodhi.local" <> Date: Tue, 27 Mar 2007 22:15:51 +0400 Subject: [PATCH 12/14] Fix spelling (recursivity -> recursion) --- mysql-test/r/events.result | 4 ++-- mysql-test/r/events_bugs.result | 2 +- mysql-test/r/ps.result | 2 +- mysql-test/t/events.test | 4 ++-- mysql-test/t/events_bugs.test | 2 +- mysql-test/t/ps.test | 2 +- sql/share/errmsg.txt | 4 ++-- sql/sql_yacc.yy | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/events.result b/mysql-test/r/events.result index 641de1571c3..b0640af0b13 100644 --- a/mysql-test/r/events.result +++ b/mysql-test/r/events.result @@ -73,7 +73,7 @@ DROP EVENT event_starts_test; create table test_nested(a int); create event e_43 on schedule every 1 second do set @a = 5; alter event e_43 do alter event e_43 do set @a = 4; -ERROR HY000: Recursivity of EVENT DDL statements is forbidden when body is present +ERROR HY000: Recursion of EVENT DDL statements is forbidden when body is present alter event e_43 do begin alter event e_43 on schedule every 5 minute; @@ -367,7 +367,7 @@ root localhost events_test Connect User lock select get_lock("test_lock2_1", 20) drop event закачка21; create table t_16 (s1 int); create trigger t_16_bi before insert on t_16 for each row create event e_16 on schedule every 1 second do set @a=5; -ERROR HY000: Recursivity of EVENT DDL statements is forbidden when body is present +ERROR HY000: Recursion of EVENT DDL statements is forbidden when body is present drop table t_16; create event white_space on schedule every 10 hour diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index 1a34f098b12..6835ecd7fde 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -17,7 +17,7 @@ DROP EVENT ДОЛЕН_регистър_утф8; SET NAMES latin1; set @a=3; CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5; -ERROR HY000: Recursivity of EVENT DDL statements is forbidden when body is present +ERROR HY000: Recursion of EVENT DDL statements is forbidden when body is present create event e_55 on schedule at 99990101000000 do drop table t; ERROR HY000: Incorrect AT value: '99990101000000' create event e_55 on schedule every 10 hour starts 99990101000000 do drop table t; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index c4e44945ec4..12608c48bf5 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -2285,7 +2285,7 @@ drop user pstest_xyz@localhost; deallocate prepare abc; drop event if exists xyz; create function func_1() returns int begin create event xyz on schedule at now() do select 123; return 1; end| -ERROR HY000: Recursivity of EVENT DDL statements is forbidden when body is present +ERROR HY000: Recursion of EVENT DDL statements is forbidden when body is present select func_1(), func_1(), func_1() from dual; ERROR 42000: FUNCTION test.func_1 does not exist drop function func_1; diff --git a/mysql-test/t/events.test b/mysql-test/t/events.test index 24f4b4eccab..39bc1063ace 100644 --- a/mysql-test/t/events.test +++ b/mysql-test/t/events.test @@ -74,7 +74,7 @@ DROP EVENT event_starts_test; # create table test_nested(a int); create event e_43 on schedule every 1 second do set @a = 5; ---error ER_EVENT_RECURSIVITY_FORBIDDEN +--error ER_EVENT_RECURSION_FORBIDDEN alter event e_43 do alter event e_43 do set @a = 4; delimiter |; alter event e_43 do @@ -351,7 +351,7 @@ drop event закачка21; # Bug #16410 Events: CREATE EVENT is legal in a CREATE TRIGGER statement # create table t_16 (s1 int); ---error ER_EVENT_RECURSIVITY_FORBIDDEN +--error ER_EVENT_RECURSION_FORBIDDEN create trigger t_16_bi before insert on t_16 for each row create event e_16 on schedule every 1 second do set @a=5; drop table t_16; # diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index c1016f1752b..56c44dc3a9f 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -30,7 +30,7 @@ SET NAMES latin1; # START - BUG#16408: Events: crash for an event in a procedure # set @a=3; ---error ER_EVENT_RECURSIVITY_FORBIDDEN +--error ER_EVENT_RECURSION_FORBIDDEN CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5; # # END - BUG#16408: Events: crash for an event in a procedure diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 9f670f9973f..44f9bf350b2 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -2324,7 +2324,7 @@ drop event if exists xyz; #drop event xyz; #drop procedure proc_1; delimiter |; ---error ER_EVENT_RECURSIVITY_FORBIDDEN +--error ER_EVENT_RECURSION_FORBIDDEN create function func_1() returns int begin create event xyz on schedule at now() do select 123; return 1; end| delimiter ;| --error ER_SP_DOES_NOT_EXIST diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index c0da7053ac2..0a40f2b9ed1 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5978,8 +5978,8 @@ ER_BASE64_DECODE_ERROR ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA eng "Triggers can not be created on system tables" ger "Trigger knnen nicht auf Systemtabellen erzeugt werden" -ER_EVENT_RECURSIVITY_FORBIDDEN - eng "Recursivity of EVENT DDL statements is forbidden when body is present" +ER_EVENT_RECURSION_FORBIDDEN + eng "Recursion of EVENT DDL statements is forbidden when body is present" ger "Rekursivitt von EVENT-DDL-Anweisungen ist unzulssig wenn ein Hauptteil (Body) existiert" ER_EVENTS_DB_ERROR eng "Cannot proceed because system tables used by Event Scheduler were found damaged at server start" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9d4c62052dd..b8dc377bb82 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1847,7 +1847,7 @@ ev_sql_stmt: */ if (lex->sphead) { - my_error(ER_EVENT_RECURSIVITY_FORBIDDEN, MYF(0)); + my_error(ER_EVENT_RECURSION_FORBIDDEN, MYF(0)); MYSQL_YYABORT; } From f85f0950a0af0c157daf664ac2b42e21d06df9de Mon Sep 17 00:00:00 2001 From: "Kristofer.Pettersson@naruto." <> Date: Mon, 2 Apr 2007 09:51:14 +0200 Subject: [PATCH 13/14] Bug#26174 Server Crash:INSERT ... SELECT ... FROM I_S.GLOBAL_STATUS in Event - Some variables in I_S.GLOBAL_STATUS were depending on a network connection in order to evaluate. Since no network connection is present during the execution of an event, this caused the server to crash. - The variable function hooks does now verify that the vio- object is valid before attempting to use it. --- mysql-test/r/information_schema.result | 28 ++++++++++++++ mysql-test/t/information_schema.test | 40 ++++++++++++++++++++ sql/mysqld.cc | 52 +++++++++++++++++--------- sql/set_var.cc | 2 +- 4 files changed, 103 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index e5d6078e863..6c03ace3d27 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1408,4 +1408,32 @@ select user,db from information_schema.processlist; user db user3148 test drop user user3148@localhost; +DROP TABLE IF EXISTS thread_status; +CREATE TABLE thread_status (variable_name VARCHAR(64), +variable_value DECIMAL(22,7)); +CREATE TABLE server_status (variable_name VARCHAR(64), +variable_value DECIMAL(22,7)); +DROP EVENT IF EXISTS log_status; +CREATE EVENT log_status +ON SCHEDULE EVERY 1 SECOND +DO +BEGIN +INSERT INTO thread_status SELECT variable_name, variable_value FROM +information_schema.session_status; +INSERT INTO server_status SELECT variable_name, variable_value FROM +information_schema.global_status; +END$$ +SET GLOBAL event_scheduler=1; +SELECT * FROM thread_status WHERE variable_name LIKE 'SSL%' LIMIT 1,2; +variable_name variable_value +SSL_ACCEPTS 0.0000000 +SSL_CALLBACK_CACHE_HITS 0.0000000 +SELECT variable_name FROM server_status LIMIT 1,2; +variable_name +ABORTED_CONNECTS +BINLOG_CACHE_DISK_USE +DROP EVENT log_status; +DROP TABLE thread_status; +DROP TABLE server_status; +SET GLOBAL event_scheduler=0; End of 5.1 tests. diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 09a588c9195..bd1f4271c94 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1042,5 +1042,45 @@ select user,db from information_schema.processlist; connection default; drop user user3148@localhost; + + +# +# Bug #26174 Server Crash: INSERT ... SELECT ... FROM I_S.GLOBAL_STATUS in Event +# +--disable_warnings +DROP TABLE IF EXISTS thread_status; +CREATE TABLE thread_status (variable_name VARCHAR(64), +variable_value DECIMAL(22,7)); +CREATE TABLE server_status (variable_name VARCHAR(64), +variable_value DECIMAL(22,7)); +DROP EVENT IF EXISTS log_status; +--enable_warnings + +DELIMITER $$; + +CREATE EVENT log_status + ON SCHEDULE EVERY 1 SECOND + DO + BEGIN + INSERT INTO thread_status SELECT variable_name, variable_value FROM +information_schema.session_status; + INSERT INTO server_status SELECT variable_name, variable_value FROM +information_schema.global_status; + END$$ + +DELIMITER ;$$ + +SET GLOBAL event_scheduler=1; +sleep 1; +SELECT * FROM thread_status WHERE variable_name LIKE 'SSL%' LIMIT 1,2; +SELECT variable_name FROM server_status LIMIT 1,2; + + + +DROP EVENT log_status; +DROP TABLE thread_status; +DROP TABLE server_status; +SET GLOBAL event_scheduler=0; + --echo End of 5.1 tests. diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 83b16d9af0a..082a7c6fcbb 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3803,6 +3803,8 @@ we force server id to 2, but this MySQL server will not act as a slave."); { if (Events::get_instance()->init()) unireg_abort(1); + } else { + Events::opt_event_scheduler= Events::EVENTS_DISABLED; } /* Signal threads waiting for server to be started */ @@ -6662,12 +6664,20 @@ static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *bu return 0; } -/* Functions relying on SSL */ +/* + Functions relying on SSL + Note: In the show_ssl_* functions, we need to check if we have a + valid vio-object since this isn't always true, specifically + when session_status or global_status is requested from + inside an Event. + */ static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_CHAR; - var->value= const_cast(thd->net.vio->ssl_arg ? - SSL_get_version((SSL*) thd->net.vio->ssl_arg) : ""); + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + var->value= const_cast(SSL_get_version((SSL*) thd->net.vio->ssl_arg)); + else + var->value= ""; return 0; } @@ -6675,9 +6685,10 @@ static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; - *((long *)buff)= (long)thd->net.vio->ssl_arg ? - SSL_session_reused((SSL*) thd->net.vio->ssl_arg) : - 0; + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + *((long *)buff)= (long)SSL_session_reused((SSL*) thd->net.vio->ssl_arg); + else + *((long *)buff)= 0; return 0; } @@ -6685,9 +6696,10 @@ static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; - *((long *)buff)= (long)thd->net.vio->ssl_arg ? - SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg) : - 0; + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + *((long *)buff)= (long)SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg); + else + *((long *)buff)= 0; return 0; } @@ -6695,9 +6707,10 @@ static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; - *((long *)buff)= (long)thd->net.vio->ssl_arg ? - SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg) : - 0; + if( thd->net.vio && thd->net.vio->ssl_arg ) + *((long *)buff)= (long)SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg); + else + *((long *)buff)= 0; return 0; } @@ -6705,17 +6718,20 @@ static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; - *((long *)buff)= (long)thd->net.vio->ssl_arg ? - SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg) : - 0; + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + *((long *)buff)= (long)SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg); + else + *((long *)buff)= 0; return 0; } static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_CHAR; - var->value= const_cast(thd->net.vio->ssl_arg ? - SSL_get_cipher((SSL*) thd->net.vio->ssl_arg) : ""); + if( thd->vio_ok() && thd->net.vio->ssl_arg ) + var->value= const_cast(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg)); + else + var->value= ""; return 0; } @@ -6723,7 +6739,7 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff) { var->type= SHOW_CHAR; var->value= buff; - if (thd->net.vio->ssl_arg) + if (thd->vio_ok() && thd->net.vio->ssl_arg) { int i; const char *p; diff --git a/sql/set_var.cc b/sql/set_var.cc index e2c90b72feb..91d2a2ec63b 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -4000,7 +4000,7 @@ sys_var_event_scheduler::update(THD *thd, set_var *var) DBUG_ENTER("sys_var_event_scheduler::update"); if (Events::opt_event_scheduler == Events::EVENTS_DISABLED) { - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--event-scheduler=DISABLED"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--event-scheduler=DISABLED or --skip-grant-tables"); DBUG_RETURN(TRUE); } From 6ca1e16e4ef6d96222bdef498bb00162000f9d21 Mon Sep 17 00:00:00 2001 From: "Kristofer.Pettersson@naruto." <> Date: Mon, 2 Apr 2007 14:03:33 +0200 Subject: [PATCH 14/14] Type cast of constant string (empty) to keep compiler happy. --- sql/mysqld.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3ab3b024643..7121ab6db78 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6742,7 +6742,7 @@ static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff) if( thd->vio_ok() && thd->net.vio->ssl_arg ) var->value= const_cast(SSL_get_version((SSL*) thd->net.vio->ssl_arg)); else - var->value= ""; + var->value= (char *)""; return 0; } @@ -6796,7 +6796,7 @@ static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff) if( thd->vio_ok() && thd->net.vio->ssl_arg ) var->value= const_cast(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg)); else - var->value= ""; + var->value= (char *)""; return 0; }