From: Date: November 1 2007 3:54pm Subject: bk commit into 5.1 tree (kostja:1.2613) BUG#12713 List-Archive: http://lists.mysql.com/commits/36888 X-Bug: 12713 Message-Id: <20071101145428.169831B024@vajra.local> Below is the list of changes that have just been committed into a local 5.1 repository of kostja. When kostja does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet@stripped, 2007-11-01 17:54:22+03:00, kostja@bodhi.(none) +1 -0 Use Internal_error_handler mechanism to silence ER_TOO_MANY_FIELDS error in mysql_create_frm instead of direct access to my_error() members. This is a pre-requisite for the patch for Bug#12713. sql/unireg.cc@stripped, 2007-11-01 17:54:20+03:00, kostja@bodhi.(none) +42 -6 Use Internal_error_handler mechanism to silence ER_TOO_MANY_FIELDS error in mysql_create_frm instead of direct access to my_error() members. diff -Nrup a/sql/unireg.cc b/sql/unireg.cc --- a/sql/unireg.cc 2007-07-11 12:57:47 +04:00 +++ b/sql/unireg.cc 2007-11-01 17:54:20 +03:00 @@ -47,6 +47,35 @@ static bool make_empty_rec(THD *thd, int uint reclength, ulong data_offset, handler *handler); +/** + An interceptor to hijack ER_TOO_MANY_FIELDS error from + pack_screens and retry again without UNIREG screens. + + XXX: what is a UNIREG screen? +*/ + +struct Pack_header_error_handler: public Internal_error_handler +{ + virtual bool handle_error(uint sql_errno, + const char *message, + MYSQL_ERROR::enum_warning_level level, + THD *thd); + bool is_handled; + Pack_header_error_handler() :is_handled(FALSE) {} +}; + + +bool +Pack_header_error_handler:: +handle_error(uint sql_errno, + const char * /* message */, + MYSQL_ERROR::enum_warning_level /* level */, + THD * /* thd */) +{ + is_handled= sql_errno == ER_TOO_MANY_FIELDS; + return is_handled; +} + /* Create a frm (table definition) file @@ -86,6 +115,8 @@ bool mysql_create_frm(THD *thd, const ch #ifdef WITH_PARTITION_STORAGE_ENGINE partition_info *part_info= thd->work_part_info; #endif + Pack_header_error_handler pack_header_error_handler; + int error; DBUG_ENTER("mysql_create_frm"); DBUG_ASSERT(*fn_rext((char*)file_name)); // Check .frm extension @@ -99,17 +130,22 @@ bool mysql_create_frm(THD *thd, const ch create_info->null_bits++; data_offset= (create_info->null_bits + 7) / 8; - if (pack_header(forminfo, ha_legacy_type(create_info->db_type), - create_fields,info_length, - screens, create_info->table_options, - data_offset, db_file)) + thd->push_internal_handler(&pack_header_error_handler); + + error= pack_header(forminfo, ha_legacy_type(create_info->db_type), + create_fields,info_length, + screens, create_info->table_options, + data_offset, db_file); + + thd->pop_internal_handler(); + + if (error) { my_free(screen_buff, MYF(0)); - if (thd->net.last_errno != ER_TOO_MANY_FIELDS) + if (! pack_header_error_handler.is_handled) DBUG_RETURN(1); // Try again without UNIREG screens (to get more columns) - thd->net.last_error[0]=0; if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,1))) DBUG_RETURN(1); if (pack_header(forminfo, ha_legacy_type(create_info->db_type),