commit f6cf77908c7dc2906be9e1c27175dffd309e5d59
Author: Thirunarayanan Balathandayuthapani <thiru@mariadb.com>
Date:   Fri Feb 28 15:55:51 2020 +0530

    MDEV-21832 FORCE all partition to rebuild if any one of
                    the partition does rebuild
    
    - During DDL, if one partition requires table rebuild and other partition
    doesn't need rebuild then all partition should be forced to rebuild.
    In commit_inplace_alter_table(), InnoDB does check to make sure all
    partition does the same alter algorithm

diff --git a/mysql-test/suite/parts/r/partition_alter_instant.result b/mysql-test/suite/parts/r/partition_alter_instant.result
new file mode 100644
index 00000000000..e5ef57db992
--- /dev/null
+++ b/mysql-test/suite/parts/r/partition_alter_instant.result
@@ -0,0 +1,34 @@
+CREATE TABLE t1 (
+id INT NOT NULL,
+name VARCHAR(30))ENGINE=InnoDB ROW_FORMAT=COMPACT CHARACTER SET=latin1
+PARTITION BY RANGE (id) (
+PARTITION p0 VALUES LESS THAN (50),
+PARTITION p1 VALUES LESS THAN (MAXVALUE)
+);
+INSERT INTO t1(id, name) VALUES(16, 'Me'), (337, 'ROFL');
+# Add and drop 31 Instant columns
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `id` int(11) NOT NULL,
+  `name` varchar(30) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
+ PARTITION BY RANGE (`id`)
+(PARTITION `p0` VALUES LESS THAN (50) ENGINE = InnoDB,
+ PARTITION `p1` VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
+ALTER TABLE t2 REMOVE PARTITIONING;
+ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `id` int(11) NOT NULL,
+  `name` varchar(30) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
+SET ALTER_ALGORITHM=INSTANT;
+ALTER TABLE t1 ADD COLUMN col1 VARCHAR(255) NOT NULL DEFAULT repeat('a', 255);
+ERROR 0A000: ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE
+SET ALTER_ALGORITHM=INPLACE;
+ALTER TABLE t1 ADD COLUMN col1 VARCHAR(255) NOT NULL DEFAULT repeat('a', 255);
+DROP TABLE t1, t2;
+SET ALTER_ALGORITHM=DEFAULT;
diff --git a/mysql-test/suite/parts/t/partition_alter_instant.test b/mysql-test/suite/parts/t/partition_alter_instant.test
new file mode 100644
index 00000000000..3d798791517
--- /dev/null
+++ b/mysql-test/suite/parts/t/partition_alter_instant.test
@@ -0,0 +1,43 @@
+--source include/have_partition.inc
+--source include/have_innodb.inc
+--source include/have_innodb_16k.inc
+
+# MDEV-21832 FORCE all partition to rebuild if any one of the
+# partition does rebuild
+CREATE TABLE t1 (
+    id INT NOT NULL,
+    name VARCHAR(30))ENGINE=InnoDB ROW_FORMAT=COMPACT CHARACTER SET=latin1
+    PARTITION BY RANGE (id) (
+        PARTITION p0 VALUES LESS THAN (50),
+        PARTITION p1 VALUES LESS THAN (MAXVALUE)
+);
+
+INSERT INTO t1(id, name) VALUES(16, 'Me'), (337, 'ROFL');
+
+--echo # Add and drop 31 Instant columns
+--disable_query_log
+let $i = 1;
+while ($i < 32) {
+--eval ALTER TABLE t1 ADD COLUMN col$i VARCHAR(255) NOT NULL DEFAULT repeat('a', 255);
+inc $i;
+}
+
+let $i = 31;
+while ($i > 0) {
+--eval ALTER TABLE t1 DROP COLUMN col$i
+dec $i;
+}
+--enable_query_log
+
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+ALTER TABLE t2 REMOVE PARTITIONING;
+ALTER TABLE t1 EXCHANGE PARTITION p0 WITH TABLE t2;
+SHOW CREATE TABLE t2;
+SET ALTER_ALGORITHM=INSTANT;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+ALTER TABLE t1 ADD COLUMN col1 VARCHAR(255) NOT NULL DEFAULT repeat('a', 255);
+SET ALTER_ALGORITHM=INPLACE;
+ALTER TABLE t1 ADD COLUMN col1 VARCHAR(255) NOT NULL DEFAULT repeat('a', 255);
+DROP TABLE t1, t2;
+SET ALTER_ALGORITHM=DEFAULT;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 53bcd4df5c5..f5ead70814e 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -10072,6 +10072,7 @@ ha_partition::check_if_supported_inplace_alter(TABLE *altered_table,
   enum_alter_inplace_result result= HA_ALTER_INPLACE_NO_LOCK;
   ha_partition_inplace_ctx *part_inplace_ctx;
   bool first_is_set= false;
+  bool force= ha_alter_info->handler_flags & ALTER_RECREATE;
   THD *thd= ha_thd();
 
   DBUG_ENTER("ha_partition::check_if_supported_inplace_alter");
@@ -10101,6 +10102,7 @@ ha_partition::check_if_supported_inplace_alter(TABLE *altered_table,
     part_inplace_ctx->handler_ctx_array[index]= NULL;
 
   ha_alter_info->handler_flags |= ALTER_PARTITIONED;
+recheck_support_alter:
   for (index= 0; index < m_tot_parts; index++)
   {
     enum_alter_inplace_result p_result=
@@ -10118,12 +10120,23 @@ ha_partition::check_if_supported_inplace_alter(TABLE *altered_table,
       DBUG_ASSERT(0);
       DBUG_RETURN(HA_ALTER_ERROR);
     }
+
     if (p_result < result)
+    {
       result= p_result;
+      force= (result == HA_ALTER_INPLACE_COPY_NO_LOCK
+              || result == HA_ALTER_INPLACE_COPY_LOCK);
+    }
     if (result == HA_ALTER_ERROR)
       break;
   }
 
+  if (force && !(ha_alter_info->handler_flags & ALTER_RECREATE))
+  {
+    ha_alter_info->handler_flags|= ALTER_RECREATE;
+    goto recheck_support_alter;
+  }
+
   ha_alter_info->handler_ctx= part_inplace_ctx;
   /*
     To indicate for future inplace calls that there are several
