From e5dfe04da02244e592db0b5955a4d95148e0928a Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 2 Nov 2016 18:04:35 +0400 Subject: MDEV-11146 SP variables of the SET data type erroneously allow values with comma There was a duplicate code to create TYPELIB from List: - In typelib() and mysql_prepare_create_table(), which was used to initialize table fields. - create_typelib() and sp_prepare_create_field(), which was used to initialize SP variables. create_typelib() was incomplete and didn't check for wrong SET values. Fix: - Moving the code from create_typelib() and mysql_prepare_create_field() to news methods Column_definition::create_interval_from_interval_list() and Column_definition::prepare_interval_field(). - Moving the code from calculate_interval_lengths() in sql_table.cc to a new method Column_definition::calculate_interval_lengths(), as it's now needed only in Column_definition::create_interval_from_interval_list() - Reusing the new method Column_definition::prepare_interval_field() in both mysql_prepare_create_table() and sp_prepare_create_field(), instead of the old duplicate code pieces - Removing global functions typelib() and create_typelib() This patch also fixes: MDEV-11155 Bad error message when creating a SET column with comma and non-ASCII characters The problem was that ErrCongString() was called with a wrong "charset" parameter. --- sql/sp_head.cc | 59 ++-------------------------------------------------------- 1 file changed, 2 insertions(+), 57 deletions(-) (limited to 'sql/sp_head.cc') diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 0b9b503aef3..c5d64618ea4 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -747,58 +747,6 @@ sp_head::set_stmt_end(THD *thd) } -static TYPELIB * -create_typelib(MEM_ROOT *mem_root, Column_definition *field_def, List *src) -{ - TYPELIB *result= NULL; - CHARSET_INFO *cs= field_def->charset; - DBUG_ENTER("create_typelib"); - - if (src->elements) - { - result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB)); - result->count= src->elements; - result->name= ""; - if (!(result->type_names=(const char **) - alloc_root(mem_root,(sizeof(char *)+sizeof(int))*(result->count+1)))) - DBUG_RETURN(0); - result->type_lengths= (uint*)(result->type_names + result->count+1); - List_iterator it(*src); - String conv; - for (uint i=0; i < result->count; i++) - { - uint32 dummy; - uint length; - String *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); - - length= conv.length(); - result->type_names[i]= (char*) strmake_root(mem_root, conv.ptr(), - length); - } - else - { - length= tmp->length(); - result->type_names[i]= strmake_root(mem_root, tmp->ptr(), length); - } - - // Strip trailing spaces. - length= cs->cset->lengthsp(cs, result->type_names[i], length); - result->type_lengths[i]= length; - ((uchar *)result->type_names[i])[length]= '\0'; - } - result->type_names[result->count]= 0; - result->type_lengths[result->count]= 0; - } - DBUG_RETURN(result); -} - - sp_head::~sp_head() { LEX *lex; @@ -2362,11 +2310,8 @@ sp_head::fill_field_definition(THD *thd, LEX *lex, if (field_def->check(thd)) return TRUE; - if (field_def->interval_list.elements) - field_def->interval= create_typelib(mem_root, field_def, - &field_def->interval_list); - - sp_prepare_create_field(thd, field_def); + if (sp_prepare_create_field(thd, mem_root, field_def)) + return true; if (prepare_create_field(field_def, &unused1, HA_CAN_GEOMETRY)) { -- cgit v1.2.1