MDEV-32013 Add Field::val_lex_string_strmake()
There are two functions to extract a Field::val_str() value as a LEX_STRING or LEX_CSTRING pointing to the data allocated on a MEM_ROOT: char *get_field(MEM_ROOT *mem, Field *field); bool get_field(MEM_ROOT *mem, Field *field, class String *res); The first function requires strlen() calls to make a LEX_CSTRING/LEX_STRING. The second function requires a redundant String buffer, which is used only as a temporary proxy value pointing to a MEM_ROOT fragment (and does not use any String dynamic allocation methods). This patch add a native way to extract a Field::val_str() value as a LEX_STRING or LEX_CSTRING pointing to a MEM_ROOT fragment. It helps to remove redundant strlen() calls and redundant String buffers. - Adding a new method: LEX_STRING Field::val_lex_string_strmake(MEM_ROOT *mem); - Reusing the new method Field::val_lex_string_strmake() in; bool get_field(MEM_ROOT *mem, Field *field, String *res); Also, moving it from table.cc to a static function in sql_help.cc. It is used in sql_help.cc only, and we don't want it to be reused in other parts of the code (to avoid redundant String buffers). - Reusing the new method Field::val_lex_string_strmake() in this function: char *get_field(MEM_ROOT *mem, Field *field); - Replacing get_field() to Field::val_lex_string_strmake() in these files: sql_plugin.cc (redundant String buffers were removed) sql_udf.cc (redundant strlen() calls were removed) Note, this function: char *get_field(MEM_ROOT *mem, Field *field); is still used in a number of files: event_data_objects.cc event_db_repository.cc sql_acl.cc sql_servers.cc These remaining calls will be removed by separate patches, and get_field() will be removed after that.
This commit is contained in:
parent
781ec16bd9
commit
e0949cd6f0
@ -11380,6 +11380,15 @@ void Field::register_field_in_read_map()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LEX_STRING Field::val_lex_string_strmake(MEM_ROOT *mem)
|
||||||
|
{
|
||||||
|
StringBuffer<MAX_FIELD_WIDTH> str;
|
||||||
|
val_str(&str);
|
||||||
|
char *to= strmake_root(mem, str.ptr(), str.length());
|
||||||
|
return to ? LEX_STRING{to, str.length()} : LEX_STRING{NULL, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Field::val_str_nopad(MEM_ROOT *mem_root, LEX_CSTRING *to)
|
bool Field::val_str_nopad(MEM_ROOT *mem_root, LEX_CSTRING *to)
|
||||||
{
|
{
|
||||||
StringBuffer<MAX_FIELD_WIDTH> str;
|
StringBuffer<MAX_FIELD_WIDTH> str;
|
||||||
|
14
sql/field.h
14
sql/field.h
@ -1055,6 +1055,20 @@ public:
|
|||||||
return to->copy((const char *) ptr, pack_length());
|
return to->copy((const char *) ptr, pack_length());
|
||||||
}
|
}
|
||||||
String *val_int_as_str(String *val_buffer, bool unsigned_flag);
|
String *val_int_as_str(String *val_buffer, bool unsigned_flag);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copy the Field::val_str() value to MEM_ROOT as a 0x00-teminated string.
|
||||||
|
|
||||||
|
@param mem_root The memory root to put the value to.
|
||||||
|
@returns {NULL,0} in case of EOM, or the field value otherwise.
|
||||||
|
|
||||||
|
Only one 0x00 terminating byte is put in the end, even in case
|
||||||
|
of complex character sets like UCS2/UTF16/UTF32.
|
||||||
|
This is OK, since this method is used to read system tables,
|
||||||
|
which are in utf8.
|
||||||
|
*/
|
||||||
|
LEX_STRING val_lex_string_strmake(MEM_ROOT *mem_root);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Return the field value as a LEX_CSTRING, without padding to full length
|
Return the field value as a LEX_CSTRING, without padding to full length
|
||||||
(MODE_PAD_CHAR_TO_FULL_LENGTH is temporarily suppressed during the call).
|
(MODE_PAD_CHAR_TO_FULL_LENGTH is temporarily suppressed during the call).
|
||||||
|
@ -69,6 +69,29 @@ enum enum_used_fields
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Allocate string field in MEM_ROOT and return it as String
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
get_field()
|
||||||
|
mem MEM_ROOT for allocating
|
||||||
|
field Field for retrieving of string
|
||||||
|
res result String
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void get_field(MEM_ROOT *mem, Field *field, String *res)
|
||||||
|
{
|
||||||
|
THD *thd= field->get_thd();
|
||||||
|
Sql_mode_instant_remove sms(thd, MODE_PAD_CHAR_TO_FULL_LENGTH);
|
||||||
|
LEX_STRING ls= field->val_lex_string_strmake(mem);
|
||||||
|
DBUG_ASSERT((!ls.str && !ls.length) || ls.str[ls.length] == '\0');
|
||||||
|
if (!ls.str)
|
||||||
|
res->length(0); // EOM
|
||||||
|
else
|
||||||
|
res->set((const char *) ls.str, ls.length, field->charset());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Fill st_find_field structure with pointers to fields
|
Fill st_find_field structure with pointers to fields
|
||||||
|
|
||||||
|
@ -1883,12 +1883,11 @@ static void plugin_load(MEM_ROOT *tmp_root)
|
|||||||
while (!(error= read_record_info.read_record()))
|
while (!(error= read_record_info.read_record()))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("init plugin record"));
|
DBUG_PRINT("info", ("init plugin record"));
|
||||||
String str_name, str_dl;
|
DBUG_ASSERT(new_thd == table->field[0]->get_thd());
|
||||||
get_field(tmp_root, table->field[0], &str_name);
|
DBUG_ASSERT(new_thd == table->field[1]->get_thd());
|
||||||
get_field(tmp_root, table->field[1], &str_dl);
|
DBUG_ASSERT(!(new_thd->variables.sql_mode & MODE_PAD_CHAR_TO_FULL_LENGTH));
|
||||||
|
LEX_CSTRING name= table->field[0]->val_lex_string_strmake(tmp_root);
|
||||||
LEX_CSTRING name= {str_name.ptr(), str_name.length()};
|
LEX_CSTRING dl= table->field[1]->val_lex_string_strmake(tmp_root);
|
||||||
LEX_CSTRING dl= {str_dl.ptr(), str_dl.length()};
|
|
||||||
|
|
||||||
if (!name.length || !dl.length)
|
if (!name.length || !dl.length)
|
||||||
continue;
|
continue;
|
||||||
|
@ -208,10 +208,11 @@ void udf_init()
|
|||||||
while (!(error= read_record_info.read_record()))
|
while (!(error= read_record_info.read_record()))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info",("init udf record"));
|
DBUG_PRINT("info",("init udf record"));
|
||||||
LEX_CSTRING name;
|
DBUG_ASSERT(!(new_thd->variables.sql_mode & MODE_PAD_CHAR_TO_FULL_LENGTH));
|
||||||
name.str=get_field(&mem, table->field[0]);
|
DBUG_ASSERT(table->field[0]->get_thd() == new_thd);
|
||||||
name.length = (uint) safe_strlen(name.str);
|
DBUG_ASSERT(table->field[2]->get_thd() == new_thd);
|
||||||
char *dl_name= get_field(&mem, table->field[2]);
|
LEX_CSTRING name= table->field[0]->val_lex_string_strmake(&mem);
|
||||||
|
LEX_CSTRING dl_name= table->field[2]->val_lex_string_strmake(&mem);
|
||||||
bool new_dl=0;
|
bool new_dl=0;
|
||||||
Item_udftype udftype=UDFTYPE_FUNCTION;
|
Item_udftype udftype=UDFTYPE_FUNCTION;
|
||||||
if (table->s->fields >= 4) // New func table
|
if (table->s->fields >= 4) // New func table
|
||||||
@ -224,7 +225,8 @@ void udf_init()
|
|||||||
|
|
||||||
On windows we must check both FN_LIBCHAR and '/'.
|
On windows we must check both FN_LIBCHAR and '/'.
|
||||||
*/
|
*/
|
||||||
if (!name.str || !dl_name || check_valid_path(dl_name, strlen(dl_name)) ||
|
if (!name.length || !dl_name.length ||
|
||||||
|
check_valid_path(dl_name.str, dl_name.length) ||
|
||||||
check_string_char_length(&name, 0, NAME_CHAR_LEN,
|
check_string_char_length(&name, 0, NAME_CHAR_LEN,
|
||||||
system_charset_info, 1))
|
system_charset_info, 1))
|
||||||
{
|
{
|
||||||
@ -234,7 +236,7 @@ void udf_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(tmp= add_udf(&name,(Item_result) table->field[1]->val_int(),
|
if (!(tmp= add_udf(&name,(Item_result) table->field[1]->val_int(),
|
||||||
dl_name, udftype)))
|
dl_name.str, udftype)))
|
||||||
{
|
{
|
||||||
sql_print_error("Can't alloc memory for udf function: '%.64s'", name.str);
|
sql_print_error("Can't alloc memory for udf function: '%.64s'", name.str);
|
||||||
continue;
|
continue;
|
||||||
|
44
sql/table.cc
44
sql/table.cc
@ -5090,40 +5090,6 @@ rename_file_ext(const char * from,const char * to,const char * ext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Allocate string field in MEM_ROOT and return it as String
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
get_field()
|
|
||||||
mem MEM_ROOT for allocating
|
|
||||||
field Field for retrieving of string
|
|
||||||
res result String
|
|
||||||
|
|
||||||
RETURN VALUES
|
|
||||||
1 string is empty
|
|
||||||
0 all ok
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool get_field(MEM_ROOT *mem, Field *field, String *res)
|
|
||||||
{
|
|
||||||
const char *to;
|
|
||||||
StringBuffer<MAX_FIELD_WIDTH> str;
|
|
||||||
bool rc;
|
|
||||||
THD *thd= field->get_thd();
|
|
||||||
Sql_mode_instant_remove sms(thd, MODE_PAD_CHAR_TO_FULL_LENGTH);
|
|
||||||
|
|
||||||
field->val_str(&str);
|
|
||||||
if ((rc= !str.length() ||
|
|
||||||
!(to= strmake_root(mem, str.ptr(), str.length()))))
|
|
||||||
{
|
|
||||||
res->length(0);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
res->set(to, str.length(), field->charset());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Allocate string field in MEM_ROOT and return it as NULL-terminated string
|
Allocate string field in MEM_ROOT and return it as NULL-terminated string
|
||||||
|
|
||||||
@ -5139,10 +5105,12 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res)
|
|||||||
|
|
||||||
char *get_field(MEM_ROOT *mem, Field *field)
|
char *get_field(MEM_ROOT *mem, Field *field)
|
||||||
{
|
{
|
||||||
String str;
|
THD *thd= field->get_thd();
|
||||||
bool rc= get_field(mem, field, &str);
|
Sql_mode_instant_remove sms(thd, MODE_PAD_CHAR_TO_FULL_LENGTH);
|
||||||
DBUG_ASSERT(rc || str.ptr()[str.length()] == '\0');
|
LEX_STRING ls= field->val_lex_string_strmake(mem);
|
||||||
return rc ? NullS : (char *) str.ptr();
|
DBUG_ASSERT((!ls.str && !ls.length) || ls.str[ls.length] == '\0');
|
||||||
|
// Empty string "" is intentionally returned as NullS
|
||||||
|
return ls.length == 0 ? NullS : ls.str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3404,7 +3404,6 @@ bool check_period_name(const char *name);
|
|||||||
bool check_table_name(const char *name, size_t length, bool check_for_path_chars);
|
bool check_table_name(const char *name, size_t length, bool check_for_path_chars);
|
||||||
int rename_file_ext(const char * from,const char * to,const char * ext);
|
int rename_file_ext(const char * from,const char * to,const char * ext);
|
||||||
char *get_field(MEM_ROOT *mem, Field *field);
|
char *get_field(MEM_ROOT *mem, Field *field);
|
||||||
bool get_field(MEM_ROOT *mem, Field *field, class String *res);
|
|
||||||
|
|
||||||
bool validate_comment_length(THD *thd, LEX_CSTRING *comment, size_t max_len,
|
bool validate_comment_length(THD *thd, LEX_CSTRING *comment, size_t max_len,
|
||||||
uint err_code, const char *name);
|
uint err_code, const char *name);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user