Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: CREATE TABLE abcÿdef (i int)engine=tianmu;Unable to insert data #362

Closed
1 task
shangyanwen opened this issue Aug 4, 2022 · 1 comment
Closed
1 task
Assignees
Labels
A-bug Something isn't working

Comments

@shangyanwen
Copy link
Contributor

Describe the problem

CREATE TABLE `abcÿdef` (i int)engine=tianmu;
INSERT INTO `abcÿdef` VALUES (1);
INSERT INTO abcÿdef VALUES (2);
SELECT * FROM `abcÿdef`;
SELECT * FROM abcÿdef;
##The error results are as follows
Empty set (0.00 sec)

Expected behavior

##The following is:innodb test result
SELECT * FROM `abcÿdef`;
+------+
| i    |
+------+
|    1 |
|    2 |
+------+
2 rows in set (0.00 sec)

How To Reproduce

CREATE TABLE `abcÿdef` (i int)engine=tianmu;
INSERT INTO `abcÿdef` VALUES (1);
INSERT INTO abcÿdef VALUES (2);
SELECT * FROM `abcÿdef`;
SELECT * FROM abcÿdef;

Environment

1. StoneDB for mysql5.7 v1.0.0 (release)
2. Ubuntu 20.04.4

Are you interested in submitting a PR to solve the problem?

  • Yes, I will!
@shangyanwen shangyanwen added the A-bug Something isn't working label Aug 4, 2022
@lylth lylth self-assigned this Aug 10, 2022
@lylth
Copy link
Contributor

lylth commented Aug 20, 2022

Delay insert process to get table name problem record

1. The problem

Failed to insert data into a table with a table name with special characters (for example, spaces)

mysql> CREATE TABLE `abc def` (i int)engine=tianmu;
Query OK, 0 rows affected (4 min 50.18 sec)

mysql> INSERT INTO `abc def` VALUES (1);
Query OK, 1 row affected (11.44 sec)

mysql> select * from `abc def`;
Empty set (2 min 15.16 sec)

2. the cause of the problem

When a table named abc def is created, the table named abc@00400020def will be converted by the strconvert() function, and the generated .frm file will be named: abc@0020def.frm.

mysql> CREATE TABLE `abc def` (i int)engine=tianmu;
Query OK, 0 rows affected (4 min 50.18 sec)

[root@localhost /stonedb57/install/data/lthdt1]$ll
-rw-r-----. 1 mysql mysql 8554 8月  12 15:43 abc@0020def.frm
drwxr-x--x. 3 mysql mysql   80 8月  12 15:43 abc@0020def.tianmu
-rw-r-----. 1 mysql mysql   67 8月  10 20:44 db.opt
-rw-r-----. 1 mysql mysql 8586 8月  11 19:18 person.frm
drwxr-x--x. 3 mysql mysql   80 8月  12 15:37 person.tianmu

The stack for creating the table is as follows:

tablename_to_filename(const char * from, char * to, size_t to_length) (\opt\litaihong\stonedb\sql\sql_table.cc:523)
build_table_filename(char * buff, size_t bufflen, const char * db, const char * table_name, const char * ext, uint flags, bool * was_truncated) (\opt\litaihong\stonedb\sql\sql_table.cc:580)
build_table_filename(char * buff, size_t bufflen, const char * db, const char * table, const char * ext, uint flags) (\opt\litaihong\stonedb\sql\sql_table.h:172)
check_if_table_exists(THD * thd, TABLE_LIST * table, bool * exists) (\opt\litaihong\stonedb\sql\sql_base.cc:2690)
open_table(THD * thd, TABLE_LIST * table_list, Open_table_context * ot_ctx) (\opt\litaihong\stonedb\sql\sql_base.cc:3321)
open_and_process_table(THD * thd, LEX * lex, TABLE_LIST * tables, uint * counter, uint flags, Prelocking_strategy * prelocking_strategy, bool has_prelocking_list, Open_table_context * ot_ctx) (\opt\litaihong\stonedb\sql\sql_base.cc:5260)
open_tables(THD * thd, TABLE_LIST ** start, uint * counter, uint flags, Prelocking_strategy * prelocking_strategy) (\opt\litaihong\stonedb\sql\sql_base.cc:5883)
open_tables(THD * thd, TABLE_LIST ** tables, uint * counter, uint flags) (\opt\litaihong\stonedb\sql\sql_base.h:468)
mysql_create_table(THD * thd, TABLE_LIST * create_table, HA_CREATE_INFO * create_info, Alter_info * alter_info) (\opt\litaihong\stonedb\sql\sql_table.cc:5511)
mysql_execute_command(THD * thd, bool first_level) (\opt\litaihong\stonedb\sql\sql_parse.cc:3299)
mysql_parse(THD * thd, Parser_state * parser_state) (\opt\litaihong\stonedb\sql\sql_parse.cc:5621)
dispatch_command(THD * thd, const COM_DATA * com_data, enum_server_command command) (\opt\litaihong\stonedb\sql\sql_parse.cc:1495)
do_command(THD * thd) (\opt\litaihong\stonedb\sql\sql_parse.cc:1034)
handle_connection(void * arg) (\opt\litaihong\stonedb\sql\conn_handler\connection_handler_per_thread.cc:313)
pfs_spawn_thread(void * arg) (\opt\litaihong\stonedb\storage\perfschema\pfs.cc:2197)

The tablename_to_filename function uses the table name abc def as a parameter to convert the table name abc@0020def through the function strconvert().
from=0x7ffca8009670 "abc def"
to=0x7ffee746280 "abc@0020def"

  length= strconvert(system_charset_info, from,
                     &my_charset_filename, to, to_length, &errors);

2. insert data process

In the HandleDelayedLoad function of the delayed insertion process of the tainmu engine, the created .frm file is used to parse the table name when obtaining the table name.

static void HandleDelayedLoad(int tid, std::vector<std::unique_ptr<char[]>> &vec) 
{
  std::string addr = std::to_string(reinterpret_cast<long>(&vec));

  std::string table_path(vec[0].get() + sizeof(int32_t));
  std::string db_name, tab_name;

  std::tie(db_name, tab_name) = GetNames(table_path);
......
}

static auto GetNames(const std::string &table_path) 
{
  auto p = fs::path(table_path);
  return std::make_tuple(p.parent_path().filename().native(), p.filename().native());
}

image

After obtaining the table name, the insertion process needs to open and lock the table, and once again use the table name abc@0020def as a parameter to call strconvert() through the function tablename_to_filename to convert the table name to abc@00400020def.

The stack is as follows:

tablename_to_filename(const char * from, char * to, size_t to_length) (\opt\litaihong\stonedb\sql\sql_table.cc:523)
build_table_filename(char * buff, size_t bufflen, const char * db, const char * table_name, const char * ext, uint flags, bool * was_truncated) (\opt\litaihong\stonedb\sql\sql_table.cc:580)
alloc_table_share(TABLE_LIST * table_list, const char * key, size_t key_length) (\opt\litaihong\stonedb\sql\table.cc:378)
get_table_share(THD * thd, TABLE_LIST * table_list, const char * key, size_t key_length, uint db_flags, int * error, my_hash_value_type hash_value) (\opt\litaihong\stonedb\sql\sql_base.cc:715)
get_table_share_with_discover(THD * thd, TABLE_LIST * table_list, const char * key, size_t key_length, uint db_flags, int * error, my_hash_value_type hash_value) (\opt\litaihong\stonedb\sql\sql_base.cc:878)
open_table(THD * thd, TABLE_LIST * table_list, Open_table_context * ot_ctx) (\opt\litaihong\stonedb\sql\sql_base.cc:3444)
open_and_process_table(THD * thd, LEX * lex, TABLE_LIST * tables, uint * counter, uint flags, Prelocking_strategy * prelocking_strategy, bool has_prelocking_list, Open_table_context * ot_ctx) (\opt\litaihong\stonedb\sql\sql_base.cc:5260)
open_tables(THD * thd, TABLE_LIST ** start, uint * counter, uint flags, Prelocking_strategy * prelocking_strategy) (\opt\litaihong\stonedb\sql\sql_base.cc:5883)
open_and_lock_tables(THD * thd, TABLE_LIST * tables, uint flags, Prelocking_strategy * prelocking_strategy) (\opt\litaihong\stonedb\sql\sql_base.cc:6607)
open_and_lock_tables(THD * thd, TABLE_LIST * tables, uint flags) (\opt\litaihong\stonedb\sql\sql_base.h:487)
mysql_load(THD * thd, sql_exchange * ex, TABLE_LIST * table_list, List<Item> & fields_vars, List<Item> & set_fields, List<Item> & set_values, enum_duplicates handle_duplicates, bool read_file_from_client) (\opt\litaihong\stonedb\sql\sql_load.cc:257)
Tianmu::core::HandleDelayedLoad(int tid, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > & vec) (\opt\litaihong\stonedb\storage\tianmu\core\engine.cpp:1134)
std::__invoke_impl<void, void (*&)(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&), int&, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&>(void (*&)(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > &) __f,  __args#0,  __args#1) (\opt\rh\devtoolset-7\root\usr\include\c++\7\bits\invoke.h:60)
std::__invoke<void (*&)(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&), int&, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&>(void (*&)(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > &) __fn,  __args#0,  __args#1) (\opt\rh\devtoolset-7\root\usr\include\c++\7\bits\invoke.h:95)
std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)>::__call<void, , 0ul, 1ul>(std::tuple<>&&, std::_Index_tuple<0ul, 1ul>)(std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)> * const this, std::tuple<> & __args) (\opt\rh\devtoolset-7\root\usr\include\c++\7\functional:467)
std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)>::operator()<, void>()(std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)> * const this) (\opt\rh\devtoolset-7\root\usr\include\c++\7\functional:551)
std::__invoke_impl<void, std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)>&>(std::__invoke_other, std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)>&)(std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)> & __f) (\opt\rh\devtoolset-7\root\usr\include\c++\7\bits\invoke.h:60)
std::__invoke<std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)>&>(std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)>&)(std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)> & __fn) (\opt\rh\devtoolset-7\root\usr\include\c++\7\bits\invoke.h:95)
std::__future_base::_Task_state<std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)>, std::allocator<int>, void ()>::_M_run()::{lambda()#1}::operator()() const(const std::__future_base::_Task_state<std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)>, std::allocator<int>, void()>::<lambda()> * const __closure) (\opt\rh\devtoolset-7\root\usr\include\c++\7\future:1421)
std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::__future_base::_Task_state<std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > > >))(int, std::vector<std::unique_ptr<char [], std::default_delete<char []> >, std::allocator<std::unique_ptr<char [], std::default_delete<char []> > > >&)>, std::allocator<int>, void ()>::_M_run()::{lambda()#1}, void>::operator()() const(const std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::__future_base::_Task_state<_Fn, _Alloc, _Res(_Args ...)>::_M_run(_Args&& ...) [with _Fn = std::_Bind<void (*(int, std::reference_wrapper<std::vector<std::unique_ptr<char []> > >))(int, std::vector<std::unique_ptr<char []> >&)>; _Alloc = std::allocator<int>; _Res = void; _Args = {}]::<lambda()>, void> * const this) (\opt\rh\devtoolset-7\root\usr\include\c++\7\future:1362)

Finally open the table in the open_tables process of inserting data as abc@00400020def
But the actual table name is abc@0020def.
Therefore, there is an error in opening the table in HandleDelayedLoad, which terminates the subsequent LoadData process.
image

path="./lthdt1/abc@00400020def.frm"
The mysql_file_open function failed to open the file 0x7fff2c00a8e8 "./lthdt1/abc@00400020def.frm".

3.solution

After HandleDelayedLoad obtains the table name from the abc@0020def.frm file, it adds the function filename_to_tablename to call, and converts the converted table name abc@0020def.frm to the original table name abc def again.

mergify bot added a commit that referenced this issue Aug 24, 2022
…able name failure.(#222)(#362) (#427)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
@RingsC RingsC closed this as completed Aug 30, 2022
@Double0101 Double0101 moved this to In Progress in StoneDB for MySQL 8.0 Apr 3, 2023
@Double0101 Double0101 moved this from In Progress to Done in StoneDB for MySQL 8.0 Apr 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants