1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-34928 CREATE TABLE does not check valid engine for log tables

Log tables cannot work with transactional InnoDB or Aria, that is
checked by ALTER TABLE for ER_UNSUPORTED_LOG_ENGINE. But it was
possible to circumvent this check with CREATE TABLE. The patch makes
the check of supported engine common for ALTER TABLE and CREATE TABLE.
This commit is contained in:
Aleksey Midenkov
2025-06-25 14:14:50 +03:00
parent 1dedd2a3b9
commit 7ab205b009
5 changed files with 82 additions and 14 deletions

View File

@@ -1022,6 +1022,37 @@ select 'evil-doing', sleep(1.1)
select 'after evil-doing', sleep(0.2)
set global log_output=default;
drop user u@localhost;
# End of 10.5 tests
#
# MDEV-34928 CREATE TABLE does not check valid engine for log tables
#
set global general_log='on';
show create table mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
`event_time` timestamp(6) NOT NULL DEFAULT current_timestamp(6) ON UPDATE current_timestamp(6),
`user_host` mediumtext NOT NULL,
`thread_id` bigint(21) unsigned NOT NULL,
`server_id` int(10) unsigned NOT NULL,
`command_type` varchar(64) NOT NULL,
`argument` mediumtext NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci COMMENT='General log'
create or replace table mysql.general_log (a int) engine=innodb;
ERROR HY000: Storage engine InnoDB cannot be used for log tables
create or replace table mysql.slow_log (a int) engine=innodb;
ERROR HY000: Storage engine InnoDB cannot be used for log tables
create temporary table t (c int) engine=innodb;
insert into t values (1);
set global log_output='table';
set session autocommit=0;
update t set c=0;
truncate t;
select a;
ERROR 42S22: Unknown column 'a' in 'SELECT'
drop temporary table t;
set @@global.log_output= @old_log_output;
set @@global.general_log= @old_general_log;
# End of 10.6 tests
SET @@global.log_output= @old_log_output;
SET @@global.slow_query_log= @old_slow_query_log;
SET @@global.general_log= @old_general_log;

View File

@@ -2,6 +2,7 @@
-- source include/not_embedded.inc
--source include/have_csv.inc
--source include/have_innodb.inc
SET SQL_MODE="";
SET @old_log_output= @@global.log_output;
@@ -1060,6 +1061,31 @@ set global log_output=default;
drop user u@localhost;
--enable_cursor_protocol
--echo # End of 10.5 tests
--echo #
--echo # MDEV-34928 CREATE TABLE does not check valid engine for log tables
--echo #
set global general_log='on';
show create table mysql.general_log;
--error ER_UNSUPORTED_LOG_ENGINE
create or replace table mysql.general_log (a int) engine=innodb;
--error ER_UNSUPORTED_LOG_ENGINE
create or replace table mysql.slow_log (a int) engine=innodb;
create temporary table t (c int) engine=innodb;
insert into t values (1);
set global log_output='table';
set session autocommit=0;
update t set c=0;
truncate t;
--error ER_BAD_FIELD_ERROR
select a;
drop temporary table t;
set @@global.log_output= @old_log_output;
set @@global.general_log= @old_general_log;
--echo # End of 10.6 tests
SET @@global.log_output= @old_log_output;
SET @@global.slow_query_log= @old_slow_query_log;
SET @@global.general_log= @old_general_log;

View File

@@ -2315,6 +2315,7 @@ struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
const Lex_table_charset_collation_attrs_st &default_cscl,
const Lex_table_charset_collation_attrs_st &convert_cscl,
const Charset_collation_context &ctx);
bool check_if_valid_log_table();
};

View File

@@ -745,6 +745,18 @@ int check_if_log_table(const TABLE_LIST *table)
}
bool HA_CREATE_INFO::check_if_valid_log_table()
{
if (!(db_type->flags & HTON_SUPPORT_LOG_TABLES) ||
(db_type == maria_hton && transactional != HA_CHOICE_NO))
{
my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0), hton_name(db_type)->str);
return true;
}
return false;
}
/**
Check if a given table is opened log table

View File

@@ -4629,6 +4629,12 @@ int create_table_impl(THD *thd,
goto err;
}
TABLE_LIST table_list;
table_list.init_one_table(&db, &table_name, 0, TL_WRITE_ALLOW_WRITE);
int log_table= check_if_log_table(&table_list);
if (log_table && create_info->check_if_valid_log_table())
goto err;
handlerton *db_type;
if (!internal_tmp_table &&
ha_table_exists(thd, &db, &table_name,
@@ -4645,12 +4651,13 @@ int create_table_impl(THD *thd,
{
(void) delete_statistics_for_table(thd, &db, &table_name);
TABLE_LIST table_list;
table_list.init_one_table(&db, &table_name, 0, TL_WRITE_ALLOW_WRITE);
table_list.table= create_info->table;
if (check_if_log_table(&table_list, TRUE, "CREATE OR REPLACE"))
if (log_table && logger.is_log_table_enabled(log_table))
{
my_error(ER_BAD_LOG_STATEMENT, MYF(0), "CREATE OR REPLACE");
goto err;
}
/*
Rollback the empty transaction started in mysql_create_table()
@@ -10417,7 +10424,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
it is the case.
TODO: this design is obsolete and will be removed.
*/
int table_kind= check_if_log_table(table_list, FALSE, NullS);
int table_kind= check_if_log_table(table_list);
const bool used_engine= create_info->used_fields & HA_CREATE_USED_ENGINE;
if (table_kind)
@@ -10432,17 +10439,8 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
/* Disable alter of log tables to unsupported engine */
if ((used_engine) &&
(!create_info->db_type || /* unknown engine */
!(create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES)))
{
unsupported:
my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0),
hton_name(create_info->db_type)->str);
create_info->check_if_valid_log_table()))
DBUG_RETURN(true);
}
if (create_info->db_type == maria_hton &&
create_info->transactional != HA_CHOICE_NO)
goto unsupported;
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (alter_info->partition_flags & ALTER_PARTITION_INFO)