stonedb icon indicating copy to clipboard operation
stonedb copied to clipboard

bug: create table `#mysql50#q.q` ,The table is not found after being created successfully

Open shangyanwen opened this issue 2 years ago • 1 comments

Describe the problem

mysql> create database `b`;
mysql> use `b`;
mysql> create table `#mysql50#q.q` (f1 int primary key) engine=tianmu;
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+-------------+
| Tables_in_b |
+-------------+
|             |
+-------------+
1 row in set (0.00 sec)

Expected behavior

#[Expected Result 1] Similar to InnoDB, put forward not to create a successful prompt
mysql> create table `#mysql50#q.q` (f1 int primary key) engine=innodb;
ERROR 1030 (HY000): Got error 1103 from storage engine

#[Expected Result 2] 
After the creation is successful, the content can be queried

How To Reproduce

mysql> create database `b`;
mysql> use `b`;
mysql> create table `#mysql50#q.q` (f1 int primary key) engine=tianmu;

Environment

[root@dev bin]# ./mysqld --version
./mysqld  Ver 5.7.36_v1.0.0_beta-StoneDB for Linux on x86_64 (build-)
build information as follow: 
        Repository address: https://github.com/stoneatom/stonedb.git:stonedb-5.7
        Branch name: stonedb-5.7
        Last commit ID: eed32f6
        Last commit time: Date:   Wed Aug 3 11:19:48 2022 +0800
        Build time: Date: Wed Aug  3 13:01:31 CST 2022

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

  • [ ] Yes, I will!

shangyanwen avatar Sep 14 '22 03:09 shangyanwen

When creating the table, Check if the name supplied is a valid mysql 5.0 name and make the name a zero length string if it's not. Note that just returning zero length is not enough : a lot of places don't check the return value and expect a zero terminated string. The stack is as follows:

tablename_to_filename(const char * from, char * to, size_t to_length) (\opt\litaihong\stonedb\sql\sql_table.cc:517)
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)
mysql_create_table_no_lock(THD * thd, const char * db, const char * table_name, HA_CREATE_INFO * create_info, Alter_info * alter_info, uint select_field_count, bool * is_trans) (\opt\litaihong\stonedb\sql\sql_table.cc:5471)
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:5527)
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 table name #mysql50#q.q is finally converted to a null value image

When the innodb engine creates a table, it checks whether the final table name is empty. The stack is as follows:

create_table_info_t::create_table_def(create_table_info_t * const this) (\opt\litaihong\stonedb\storage\innobase\handler\ha_innodb.cc:9986)
create_table_info_t::create_table(create_table_info_t * const this) (\opt\litaihong\stonedb\storage\innobase\handler\ha_innodb.cc:11943)
ha_innobase::create(ha_innobase * const this, const char * name, TABLE * form, HA_CREATE_INFO * create_info) (\opt\litaihong\stonedb\storage\innobase\handler\ha_innodb.cc:12292)
handler::ha_create(handler * const this, const char * name, TABLE * form, HA_CREATE_INFO * info) (\opt\litaihong\stonedb\sql\handler.cc:5020)
ha_create_table(THD * thd, const char * path, const char * db, const char * table_name, HA_CREATE_INFO * create_info, bool update_create_info, bool is_temp_table) (\opt\litaihong\stonedb\sql\handler.cc:5179)
rea_create_table(THD * thd, const char * path, const char * db, const char * table_name, HA_CREATE_INFO * create_info, List<Create_field> & create_fields, uint keys, KEY * key_info, handler * file, bool no_ha_table) (\opt\litaihong\stonedb\sql\unireg.cc:563)
create_table_impl(THD * thd, const char * db, const char * table_name, const char * error_table_name, const char * path, HA_CREATE_INFO * create_info, Alter_info * alter_info, bool internal_tmp_table, uint select_field_count, bool no_ha_table, bool * is_trans, KEY ** key_info, uint * key_count) (\opt\litaihong\stonedb\sql\sql_table.cc:5353)
mysql_create_table_no_lock(THD * thd, const char * db, const char * table_name, HA_CREATE_INFO * create_info, Alter_info * alter_info, uint select_field_count, bool * is_trans) (\opt\litaihong\stonedb\sql\sql_table.cc:5483)
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:5527)
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)

image

When the tianmu engine creates a table, there is no check that the length of the table name is empty, so the modification scheme needs to add relevant code

lylth avatar Sep 28 '22 08:09 lylth

Result from tianmu in StoneDB 8.0:

mysql> use a;
Database changed
mysql> create table `#mysql50#q.q` (f1 int primary key) engine=tianmu;
Query OK, 0 rows affected (0.06 sec)

mysql> show tables;
+--------------+
| Tables_in_a  |
+--------------+
| #mysql50#q.q |
+--------------+
1 row in set (0.01 sec)

Result in InnoDB:

mysql> use b;
Database changed
mysql> create table `#mysql50#q.q` (f1 int primary key) engine=InnoDB;
Query OK, 0 rows affected (0.08 sec)

mysql> show tables;
+--------------+
| Tables_in_b  |
+--------------+
| #mysql50#q.q |
+--------------+
1 row in set (0.02 sec)

Result from Stonedb 8.0 equal to MySQL8.0

Double0101 avatar Apr 04 '23 09:04 Double0101