Hi, Aleksey! On Oct 20, Aleksey Midenkov wrote:
Recent refactorings of replacing C strings with LEX_CSTRING which is no doubt a good thing raise some questions:
1. Is it still guaranteed that Field::field_name.str is NULL-terminated?
I think it's still the case, yes. What code relies on it?
2. It is still passed as a pointer to functions. Why is that?
The main feature of C++ references is that it cannot be NULL, so we get segfault on top of the stack (closer to a cause), not the bottom of it. I see that pointers are now widely used and mainly assumed to be always non-NULL (i.e. dereferenced without assertion). But placing such implicit contract on data is not evident and bug-prone. IMHO it's much better to use references whenever it is possible (and when there is no need in cosy NULL semantic). What do you think?
This is something that gets raised over and over. Some prefer C-style pointers over references, so that when you look at the function call: func(a,&b); you can immediately see that `a` is passed by value and cannot be modified by `func`, while `b` can. Others prefer C++ references. I personally reside on the middle ground, where one uses pointers to pass "out" parameters, and const references for "in" parameters.
But for such lightweight structs like LEX_CSTRING it is even better to pass by value, so we could have the conventience of type cast.
What do you mean by that?
3. LEX_CSTRING and LEX_STRING are now non-convertible. Why not to make:
template <typename char_t> struct st_mysql_lex_string { char_t *str; size_t length; };
typedef st_mysql_lex_string<char *> LEX_STRING; typedef st_mysql_lex_string<const char *> LEX_CSTRING; typedef st_mysql_lex_string<const unsigned char *> LEX_CUSTRING;
?
What would that change?
4. There are some duplicate types: MYSQL_LEX_STRING, MYSQL_CONST_LEX_STRING. Why?
These are names used in the plugin API. They start from MYSQL_* to avoid possible name clashes with third-party code. Regards, Sergei Chief Architect MariaDB and security@mariadb.org