summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2023-05-15 19:39:21 +0300
committerNikita Malyavin <nikitamalyavin@gmail.com>2023-05-15 19:43:52 +0300
commitf4b04ec534d0ca96b9f64432c24d3e012329173f (patch)
treea770860182a397cfe109e9d39b82be7135de2543 /sql/sql_table.cc
parenta6b49437424c6322b4702532d5959e7f6632a258 (diff)
downloadmariadb-git-f4b04ec534d0ca96b9f64432c24d3e012329173f.tar.gz
MDEV-30984 Online ALTER table is denied with non-informative error messages
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc63
1 files changed, 48 insertions, 15 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 99570008ddb..9d19d4f6311 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -9916,6 +9916,53 @@ bool online_alter_check_autoinc(const THD *thd, const Alter_info *alter_info,
return online;
}
+bool online_alter_is_supported(THD *thd, const Alter_info *alter_info,
+ const TABLE *table)
+{
+ const char *reason= NULL;
+ List<FOREIGN_KEY_INFO> fk_list;
+
+ if (table->s->tmp_table)
+ {
+ reason= "Temporary tables are";
+ goto unsupported;
+ }
+
+ if (table->versioned(VERS_TRX_ID))
+ {
+ reason= "Transaction-versioned tables are";
+ goto unsupported;
+ }
+
+ table->file->get_foreign_key_list(thd, &fk_list);
+ for (auto &fk: fk_list)
+ {
+ if (fk_modifies_child(fk.delete_method)
+ || fk_modifies_child(fk.update_method))
+ {
+ reason= "Tables with CASCADE/SET NULL foreign keys are";
+ goto unsupported;
+ }
+ }
+
+ if (!online_alter_check_autoinc(thd, alter_info, table))
+ {
+ reason= "Adding AUTOINC to an existing column for a table without a "
+ "primary key is";
+ goto unsupported;
+ }
+
+ return true;
+
+unsupported:
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_ALTER_OPERATION_NOT_SUPPORTED_REASON,
+ "%s incompatible with "
+ "LOCK=NONE, ALGORITHM=COPY",
+ reason);
+ return false;
+}
+
/**
Alter table
@@ -10139,21 +10186,7 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db,
table= table_list->table;
bool is_reg_table= table->s->tmp_table == NO_TMP_TABLE;
- online= online && !table->s->tmp_table && !table->versioned(VERS_TRX_ID);
-
- List<FOREIGN_KEY_INFO> fk_list;
- table->file->get_foreign_key_list(thd, &fk_list);
- for (auto &fk: fk_list)
- {
- if (fk_modifies_child(fk.delete_method)
- || fk_modifies_child(fk.update_method))
- {
- online= false;
- break;
- }
- }
-
- online= online && online_alter_check_autoinc(thd, alter_info, table);
+ online= online && online_alter_is_supported(thd, alter_info, table);
#ifdef WITH_WSREP
if (WSREP(thd) &&