mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
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
7 changed files with 65 additions and 51 deletions
|
@ -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)
|
||||
{
|
||||
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());
|
||||
}
|
||||
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
|
||||
(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
|
||||
|
||||
|
|
|
@ -1883,12 +1883,11 @@ static void plugin_load(MEM_ROOT *tmp_root)
|
|||
while (!(error= read_record_info.read_record()))
|
||||
{
|
||||
DBUG_PRINT("info", ("init plugin record"));
|
||||
String str_name, str_dl;
|
||||
get_field(tmp_root, table->field[0], &str_name);
|
||||
get_field(tmp_root, table->field[1], &str_dl);
|
||||
|
||||
LEX_CSTRING name= {str_name.ptr(), str_name.length()};
|
||||
LEX_CSTRING dl= {str_dl.ptr(), str_dl.length()};
|
||||
DBUG_ASSERT(new_thd == table->field[0]->get_thd());
|
||||
DBUG_ASSERT(new_thd == table->field[1]->get_thd());
|
||||
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 dl= table->field[1]->val_lex_string_strmake(tmp_root);
|
||||
|
||||
if (!name.length || !dl.length)
|
||||
continue;
|
||||
|
|
|
@ -208,10 +208,11 @@ void udf_init()
|
|||
while (!(error= read_record_info.read_record()))
|
||||
{
|
||||
DBUG_PRINT("info",("init udf record"));
|
||||
LEX_CSTRING name;
|
||||
name.str=get_field(&mem, table->field[0]);
|
||||
name.length = (uint) safe_strlen(name.str);
|
||||
char *dl_name= get_field(&mem, table->field[2]);
|
||||
DBUG_ASSERT(!(new_thd->variables.sql_mode & MODE_PAD_CHAR_TO_FULL_LENGTH));
|
||||
DBUG_ASSERT(table->field[0]->get_thd() == new_thd);
|
||||
DBUG_ASSERT(table->field[2]->get_thd() == new_thd);
|
||||
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;
|
||||
Item_udftype udftype=UDFTYPE_FUNCTION;
|
||||
if (table->s->fields >= 4) // New func table
|
||||
|
@ -224,7 +225,8 @@ void udf_init()
|
|||
|
||||
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,
|
||||
system_charset_info, 1))
|
||||
{
|
||||
|
@ -234,7 +236,7 @@ void udf_init()
|
|||
}
|
||||
|
||||
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);
|
||||
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
|
||||
|
||||
|
@ -5139,10 +5105,12 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res)
|
|||
|
||||
char *get_field(MEM_ROOT *mem, Field *field)
|
||||
{
|
||||
String str;
|
||||
bool rc= get_field(mem, field, &str);
|
||||
DBUG_ASSERT(rc || str.ptr()[str.length()] == '\0');
|
||||
return rc ? NullS : (char *) str.ptr();
|
||||
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');
|
||||
// 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);
|
||||
int rename_file_ext(const char * from,const char * to,const char * ext);
|
||||
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,
|
||||
uint err_code, const char *name);
|
||||
|
|
Loading…
Add table
Reference in a new issue