[MDEV-32013] Add Field::val_lex_string_strmake() Created: 2023-08-25  Updated: 2023-09-12  Resolved: 2023-08-25

Status: Closed
Project: MariaDB Server
Component/s: Character Sets
Fix Version/s: 11.3.0

Type: Task Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Blocks
blocks MDEV-31531 Remove my_casedn_str() and my_caseup_... In Testing
blocks MDEV-31606 Refactor check_db_name() to get a con... Closed

 Description   

As of 11.3.0, the server code uses two ways to put a Field::val_str() value to MEM_ROOT:

char *get_field(MEM_ROOT *mem, Field *field);
bool get_field(MEM_ROOT *mem, Field *field, class String *res);

In many cases the value is further needed as a LEX_CSTRING, but both versions of get_field() are inconvenient and inefficient to initialize a LEX_CSTRING.

The first version requires an strlen() call. This is an example from udf_init() in sql_udf.cc:

    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]);
 
    ...
 
    if (!name.str || !dl_name || check_valid_path(dl_name, strlen(dl_name)) ||

Notice safe_strlen() and strlen() calls.

The second version of get_field() requires a String buffer for every LEX_CSTRING. This is an example from plugin_load() in sql_plugin.cc:

    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()};

Notice two String buffers.

Let's add a native method in Field which will overcome both problems:

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};
}

It won't need neither strlen() calls nor String buffers.

Also let's move this version of get_field():

bool get_field(MEM_ROOT *mem, Field *field, String *res)

as a static function to sql_help.cc, as it's only used in this file. This will help to avoid reincarnation of its calls around the code in the future and encorage the use of the new method Field::val_lex_string_strmake().



 Comments   
Comment by Vicențiu Ciorbaru [ 2023-08-25 ]

Suggest to not have the final strmake suffix. Just val_lex_string should suffice.

Comment by Alexander Barkov [ 2023-08-25 ]

I think the suffix is needed to make it clear that it puts the trailing '\0', like strmake(), strmake_root(), strmake_buf() do.

Comment by Vicențiu Ciorbaru [ 2023-08-26 ]

LEX_STRINGS should always be '\0' terminted, hence I don't think that is necessary

Generated at Thu Feb 08 10:28:09 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.