From: Date: April 19 2005 10:09am Subject: bk commit into 5.0 tree (acurtis:1.1854) BUG#9102 List-Archive: http://lists.mysql.com/internals/24128 X-Bug: 9102 Message-Id: <200504190809.j3J89l7Y078219@ltantony.xiphis.org> Below is the list of changes that have just been committed into a local 5.0 repository of acurtis. When acurtis 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 1.1854 05/04/19 09:09:25 acurtis@stripped +6 -0 Bug#9102 - Stored proccedures: function which returns blob causes crash Initialization of fields for sp return type was not complete. sql/sql_yacc.yy 1.365 05/04/19 09:09:12 acurtis@stripped +12 -2 Bug#9102 sql/sql_table.cc 1.239 05/04/19 09:09:11 acurtis@stripped +71 -0 Bug#9102 new function - sp_prepare_create_field() prepares create_field in similar way to mysql_prepare_table() sql/sp_head.cc 1.127 05/04/19 09:09:11 acurtis@stripped +25 -1 Strip spaces and do charset conversion for sp function typelibs sql/mysql_priv.h 1.289 05/04/19 09:09:11 acurtis@stripped +1 -0 Bug#9102 new function: sp_prepare_create_field() mysql-test/t/sp.test 1.109 05/04/19 09:09:10 acurtis@stripped +9 -0 Bug#9102 Test for bug mysql-test/r/sp.result 1.114 05/04/19 09:09:10 acurtis@stripped +6 -0 Bug#9102 Test for bug # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: acurtis # Host: ltantony.xiphis.org # Root: /.amd_mnt/bk.anubis/host/work-acurtis/bug9102 --- 1.288/sql/mysql_priv.h 2005-04-07 17:24:08 +01:00 +++ 1.289/sql/mysql_priv.h 2005-04-19 09:09:11 +01:00 @@ -647,6 +647,7 @@ Item ***copy_func, Field **from_field, bool group, bool modify_item, uint convert_blob_length); +void sp_prepare_create_field(THD *thd, create_field *sql_field); int prepare_create_field(create_field *sql_field, uint *blob_columns, int *timestamps, int *timestamps_with_niladic, --- 1.238/sql/sql_table.cc 2005-04-12 19:11:55 +01:00 +++ 1.239/sql/sql_table.cc 2005-04-19 09:09:11 +01:00 @@ -1352,6 +1352,77 @@ /* + Preparation of create_field for SP function return values. + Based on code used in the inner loop of mysql_prepare_table() above + + SYNOPSIS + sp_prepare_create_field() + thd Thread object + sql_field Field to prepare + + DESCRIPTION + Prepares the field structures for field creation. + +*/ + +void sp_prepare_create_field(THD *thd, create_field *sql_field) +{ + if (sql_field->sql_type == FIELD_TYPE_SET || + sql_field->sql_type == FIELD_TYPE_ENUM) + { + uint32 field_length, dummy; + if (sql_field->sql_type == FIELD_TYPE_SET) + { + calculate_interval_lengths(sql_field->charset, + sql_field->interval, &dummy, + &field_length); + sql_field->length= field_length + + (sql_field->interval->count - 1); + } + else /* FIELD_TYPE_ENUM */ + { + calculate_interval_lengths(sql_field->charset, + sql_field->interval, + &field_length, &dummy); + sql_field->length= field_length; + } + set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1); + } + + if (sql_field->sql_type == FIELD_TYPE_BIT) + { + sql_field->pack_flag= FIELDFLAG_NUMBER | + FIELDFLAG_TREAT_BIT_AS_CHAR; + } + sql_field->create_length_to_internal_length(); + + if (sql_field->length > MAX_FIELD_VARCHARLENGTH && + !(sql_field->flags & BLOB_FLAG)) + { + /* Convert long VARCHAR columns to TEXT or BLOB */ + char warn_buff[MYSQL_ERRMSG_SIZE]; + + sql_field->sql_type= FIELD_TYPE_BLOB; + sql_field->flags|= BLOB_FLAG; + sprintf(warn_buff, ER(ER_AUTO_CONVERT), sql_field->field_name, + "VARCHAR", + (sql_field->charset == &my_charset_bin) ? "BLOB" : "TEXT"); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT, + warn_buff); + } + + if ((sql_field->flags & BLOB_FLAG) && sql_field->length) + { + if (sql_field->sql_type == FIELD_TYPE_BLOB) + { + /* The user has given a length to the blob column */ + sql_field->sql_type= get_blob_type_from_length(sql_field->length); + sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0); + } + sql_field->length= 0; // Probably from an item + } +} +/* Create a table SYNOPSIS --- 1.364/sql/sql_yacc.yy 2005-04-18 10:26:55 +01:00 +++ 1.365/sql/sql_yacc.yy 2005-04-19 09:09:12 +01:00 @@ -1407,6 +1407,16 @@ lex->uint_geom_type))) YYABORT; + sp->m_returns_cs= new_field->charset; + + if (new_field->sql_type == FIELD_TYPE_SET || + new_field->sql_type == FIELD_TYPE_ENUM) + { + new_field->interval= + sp->create_typelib(&new_field->interval_list); + } + sp_prepare_create_field(YYTHD, new_field); + if (prepare_create_field(new_field, &unused1, &unused2, &unused2, 0)) YYABORT; @@ -1415,8 +1425,8 @@ sp->m_returns_cs= new_field->charset; sp->m_returns_len= new_field->length; sp->m_returns_pack= new_field->pack_flag; - sp->m_returns_typelib= - sp->create_typelib(&new_field->interval_list); + sp->m_returns_typelib= new_field->interval; + new_field->interval= NULL; bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); } --- 1.113/mysql-test/r/sp.result 2005-04-15 10:06:18 +01:00 +++ 1.114/mysql-test/r/sp.result 2005-04-19 09:09:10 +01:00 @@ -2958,4 +2958,10 @@ set global query_cache_size = @qcs1| delete from t1| drop function bug9902| +drop function if exists bug9102| +create function bug9102() returns blob return 'a'| +select bug9102(); +drop function bug9102| +bug9102() +a drop table t1,t2; --- 1.108/mysql-test/t/sp.test 2005-04-15 10:06:18 +01:00 +++ 1.109/mysql-test/t/sp.test 2005-04-19 09:09:10 +01:00 @@ -3627,6 +3627,15 @@ delete from t1| drop function bug9902| +# +# BUG#9102: New bug synopsis +# +--disable_warnings +drop function if exists bug9102| +--enable_warnings +create function bug9102() returns blob return 'a'| +select bug9102(); +drop function bug9102| # # BUG#NNNN: New bug synopsis --- 1.126/sql/sp_head.cc 2005-04-14 13:52:30 +01:00 +++ 1.127/sql/sp_head.cc 2005-04-19 09:09:11 +01:00 @@ -370,6 +370,7 @@ sp_head::create_typelib(List *src) { TYPELIB *result= NULL; + CHARSET_INFO *cs= m_returns_cs; DBUG_ENTER("sp_head::clone_typelib"); if (src->elements) { @@ -380,8 +381,31 @@ alloc_root(mem_root,sizeof(char *)*(result->count+1)))) return 0; List_iterator it(*src); + String conv, *tmp; + uint32 dummy; for (uint i=0; icount; i++) - result->type_names[i]= strdup_root(mem_root, (it++)->c_ptr()); + { + tmp = it++; + if (String::needs_conversion(tmp->length(), tmp->charset(), + cs, &dummy)) + { + uint cnv_errs; + conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs); + char *buf= (char*) alloc_root(mem_root,conv.length()+1); + memcpy(buf, conv.ptr(), conv.length()); + buf[conv.length()]= '\0'; + result->type_names[i]= buf; + result->type_lengths[i]= conv.length(); + } + else + result->type_names[i]= strdup_root(mem_root, tmp->c_ptr()); + + // Strip trailing spaces. + uint lengthsp= cs->cset->lengthsp(cs, result->type_names[i], + result->type_lengths[i]); + result->type_lengths[i]= lengthsp; + ((uchar *)result->type_names[i])[lengthsp]= '\0'; + } result->type_names[result->count]= 0; } return result;