diff --git a/include/my_base.h b/include/my_base.h
index c688591e1d53a4a2a59b4800ece011e2eb7a5034..5ea3795f7156c3138a39ba026f411f6ec6092e01 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -343,8 +343,9 @@ enum ha_base_keytype {
 #define HA_ERR_NO_CONNECTION     157  /* Could not connect to storage engine */
 #define HA_ERR_NULL_IN_SPATIAL   158  /* NULLs are not supported in spatial index */
 #define HA_ERR_TABLE_DEF_CHANGED 159  /* The table changed in storage engine */
+#define HA_ERR_NO_PARTITION_FOUND 160  /* There's no partition in table for given value */
 
-#define HA_ERR_LAST              159  /*Copy last error nr.*/
+#define HA_ERR_LAST              160  /*Copy last error nr.*/
 /* Add error numbers before HA_ERR_LAST and change it accordingly. */
 #define HA_ERR_ERRORS            (HA_ERR_LAST - HA_ERR_FIRST + 1)
 
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index f0500c639a310983f5be081f740370ba6d5d5b7f..58f026816822d1799481645ebffd285d2010fa03 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -114,3 +114,37 @@ CREATE TABLE `t1` (
 SELECT * FROM t1;
 id
 drop table t1;
+create table t1
+(a int)
+partition by range (a)
+( partition p0 values less than(10),
+partition p1 values less than (20),
+partition p2 values less than maxvalue);
+alter table t1 reorganise partition p2 into (partition p2 values less than (30));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (10) ENGINE = MyISAM, PARTITION p1 VALUES LESS THAN (20) ENGINE = MyISAM, PARTITION p2 VALUES LESS THAN (30) ENGINE = MyISAM)
+drop table t1;
+CREATE TABLE t1 (a int, b int)
+PARTITION BY RANGE (a)
+(PARTITION x0 VALUES LESS THAN (2),
+PARTITION x1 VALUES LESS THAN (4),
+PARTITION x2 VALUES LESS THAN (6),
+PARTITION x3 VALUES LESS THAN (8),
+PARTITION x4 VALUES LESS THAN (10),
+PARTITION x5 VALUES LESS THAN (12),
+PARTITION x6 VALUES LESS THAN (14),
+PARTITION x7 VALUES LESS THAN (16),
+PARTITION x8 VALUES LESS THAN (18),
+PARTITION x9 VALUES LESS THAN (20));
+ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2 INTO
+(PARTITION x1 VALUES LESS THAN (6));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) default NULL,
+  `b` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY RANGE (a) (PARTITION x1 VALUES LESS THAN (6) ENGINE = MyISAM, PARTITION x3 VALUES LESS THAN (8) ENGINE = MyISAM, PARTITION x4 VALUES LESS THAN (10) ENGINE = MyISAM, PARTITION x5 VALUES LESS THAN (12) ENGINE = MyISAM, PARTITION x6 VALUES LESS THAN (14) ENGINE = MyISAM, PARTITION x7 VALUES LESS THAN (16) ENGINE = MyISAM, PARTITION x8 VALUES LESS THAN (18) ENGINE = MyISAM, PARTITION x9 VALUES LESS THAN (20) ENGINE = MyISAM)
+drop table t1;
diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result
index 58c42888ae74811e09140021e3d4c602c69efa50..90faa3b20b86cf7c360ca84213d27e51c0854dd0 100644
--- a/mysql-test/r/partition_error.result
+++ b/mysql-test/r/partition_error.result
@@ -544,3 +544,8 @@ partitions 2
 partition x2 values in (5));
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '4,
 partition x2 values in (5))' at line 8
+CREATE TABLE t1(a int)
+PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN(5));
+insert into t1 values (10);
+ERROR HY000: Table has no partition for value 10
+drop table t1;
diff --git a/mysql-test/r/partition_list.result b/mysql-test/r/partition_list.result
index 23185e8aabf725bc23a2900be514fee99fc3c20c..21c23fd68ea48c48105a64a4712f7cd11dac0fa4 100644
--- a/mysql-test/r/partition_list.result
+++ b/mysql-test/r/partition_list.result
@@ -9,16 +9,16 @@ partitions 2
 partition x234 values in (4,7,8));
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (2,1,1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 2
 INSERT into t1 VALUES (3,1,1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 3
 INSERT into t1 VALUES (4,1,1);
 INSERT into t1 VALUES (5,1,1);
 INSERT into t1 VALUES (6,1,1);
 INSERT into t1 VALUES (7,1,1);
 INSERT into t1 VALUES (8,1,1);
 INSERT into t1 VALUES (9,1,1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 9
 INSERT into t1 VALUES (1,2,1);
 INSERT into t1 VALUES (1,3,1);
 INSERT into t1 VALUES (1,4,1);
@@ -137,7 +137,7 @@ a	b	c
 7	4	1
 INSERT into t1 VALUES (6,2,1);
 INSERT into t1 VALUES (2,2,1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 2
 drop table t1;
 CREATE TABLE t1 (
 a int not null,
@@ -156,7 +156,7 @@ subpartition x22 nodegroup 1)
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
 INSERT into t1 VALUES (7,1,1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 7
 UPDATE t1 SET a=5 WHERE a=1;
 SELECT * from t1;
 a	b	c
diff --git a/mysql-test/r/partition_mgm_err.result b/mysql-test/r/partition_mgm_err.result
index ca56dc4466624a41d466ac124365bf4a6036adbb..01709e726bd98e4754e5135aff7728f653a9fd59 100644
--- a/mysql-test/r/partition_mgm_err.result
+++ b/mysql-test/r/partition_mgm_err.result
@@ -26,7 +26,7 @@ ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10 INTO
 (PARTITION x11 VALUES LESS THAN (22));
 ERROR HY000: More partitions to reorganise than there are partitions
 ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2 INTO
-(PARTITION x1 VALUES LESS THAN (6));
+(PARTITION x3 VALUES LESS THAN (6));
 ERROR HY000: All partitions must have unique names in the table
 ALTER TABLE t1 REORGANISE PARTITION x0, x2 INTO
 (PARTITION x11 VALUES LESS THAN (2));
diff --git a/mysql-test/r/partition_range.result b/mysql-test/r/partition_range.result
index f8b4f1b054b64a4be2c29d912fbeb7b2ab6f516f..072c51cc83940898dfc36d2f374b58acc49334c3 100644
--- a/mysql-test/r/partition_range.result
+++ b/mysql-test/r/partition_range.result
@@ -94,7 +94,7 @@ INSERT into t1 values (1, 1, 1);
 INSERT into t1 values (6, 1, 1);
 INSERT into t1 values (10, 1, 1);
 INSERT into t1 values (15, 1, 1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 15
 select * from t1;
 a	b	c
 1	1	1
@@ -206,7 +206,7 @@ subpartition x22 engine myisam nodegroup 1)
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
 INSERT into t1 VALUES (5,1,1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 5
 SELECT * from t1;
 a	b	c
 1	1	1
@@ -243,7 +243,7 @@ subpartition x22 tablespace t2 engine myisam)
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
 INSERT into t1 VALUES (5,1,1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 5
 SELECT * from t1;
 a	b	c
 1	1	1
@@ -280,7 +280,7 @@ subpartition x22 tablespace t2)
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
 INSERT into t1 VALUES (5,1,1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 5
 SELECT * from t1;
 a	b	c
 1	1	1
@@ -317,7 +317,7 @@ subpartition x22 engine myisam)
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
 INSERT into t1 VALUES (5,1,1);
-ERROR HY000: Got error 1 from storage engine
+ERROR HY000: Table has no partition for value 5
 SELECT * from t1;
 a	b	c
 1	1	1
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 8f20f7be5365a85feea5e94cee4fd331948cf9cf..8b1c3f5807187cbb9608ca4f72ab8c8a6aa2249c 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -172,3 +172,34 @@ SELECT * FROM t1;
 
 drop table t1;
 
+#
+# BUG 15221 (Cannot reorganize with the same name)
+#
+create table t1
+(a int)
+partition by range (a)
+  ( partition p0 values less than(10),
+    partition p1 values less than (20),
+    partition p2 values less than maxvalue);
+
+alter table t1 reorganise partition p2 into (partition p2 values less than (30));
+show create table t1;
+drop table t1;
+
+CREATE TABLE t1 (a int, b int)
+PARTITION BY RANGE (a)
+(PARTITION x0 VALUES LESS THAN (2),
+ PARTITION x1 VALUES LESS THAN (4),
+ PARTITION x2 VALUES LESS THAN (6),
+ PARTITION x3 VALUES LESS THAN (8),
+ PARTITION x4 VALUES LESS THAN (10),
+ PARTITION x5 VALUES LESS THAN (12),
+ PARTITION x6 VALUES LESS THAN (14),
+ PARTITION x7 VALUES LESS THAN (16),
+ PARTITION x8 VALUES LESS THAN (18),
+ PARTITION x9 VALUES LESS THAN (20));
+
+ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2 INTO
+(PARTITION x1 VALUES LESS THAN (6));
+show create table t1;
+drop table t1;
diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test
index b4851dcf8c000fbff79a00a9833a032a94da55b1..ea12bbc52077209cb88c027595044591f24c3a0a 100644
--- a/mysql-test/t/partition_error.test
+++ b/mysql-test/t/partition_error.test
@@ -727,3 +727,11 @@ partitions 2
 (partition x1 values in 4,
  partition x2 values in (5));
 
+#
+# No partition for the given value
+#
+CREATE TABLE t1(a int)
+  PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN(5));
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
+insert into t1 values (10);
+drop table t1;
diff --git a/mysql-test/t/partition_list.test b/mysql-test/t/partition_list.test
index cb8d06a11ed9ae5aa16235292b5e6b7edda07803..af99321dcb22a2b75b94a161d3ac209d2609793f 100644
--- a/mysql-test/t/partition_list.test
+++ b/mysql-test/t/partition_list.test
@@ -22,16 +22,16 @@ partitions 2
  partition x234 values in (4,7,8));
 
 INSERT into t1 VALUES (1,1,1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 VALUES (2,1,1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 VALUES (3,1,1);
 INSERT into t1 VALUES (4,1,1);
 INSERT into t1 VALUES (5,1,1);
 INSERT into t1 VALUES (6,1,1);
 INSERT into t1 VALUES (7,1,1);
 INSERT into t1 VALUES (8,1,1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 VALUES (9,1,1);
 INSERT into t1 VALUES (1,2,1);
 INSERT into t1 VALUES (1,3,1);
@@ -64,7 +64,7 @@ partitions 2
  partition x234 values in (4,7,8));
 SELECT * from t1;
 INSERT into t1 VALUES (6,2,1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 VALUES (2,2,1);
 
 drop table t1;
@@ -89,7 +89,7 @@ subpartition by hash (a+b)
 
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 VALUES (7,1,1);
 UPDATE t1 SET a=5 WHERE a=1;
 SELECT * from t1;
diff --git a/mysql-test/t/partition_mgm_err.test b/mysql-test/t/partition_mgm_err.test
index 1d9d8a79f3da005b77d42401f66bac836a02806a..92848fc135e2ba12388555da160d50aae6e03f72 100644
--- a/mysql-test/t/partition_mgm_err.test
+++ b/mysql-test/t/partition_mgm_err.test
@@ -43,7 +43,7 @@ ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10 INTO
 
 --error ER_SAME_NAME_PARTITION
 ALTER TABLE t1 REORGANISE PARTITION x0,x1,x2 INTO
-(PARTITION x1 VALUES LESS THAN (6));
+(PARTITION x3 VALUES LESS THAN (6));
 
 --error ER_CONSECUTIVE_REORG_PARTITIONS
 ALTER TABLE t1 REORGANISE PARTITION x0, x2 INTO
diff --git a/mysql-test/t/partition_range.test b/mysql-test/t/partition_range.test
index 08cc841b12ef7565166e5eb23d0da4e55333f50b..9a81914ed2d7c8f51ab56db923ff979d9c22cb98 100644
--- a/mysql-test/t/partition_range.test
+++ b/mysql-test/t/partition_range.test
@@ -97,7 +97,7 @@ partitions 3
 INSERT into t1 values (1, 1, 1);
 INSERT into t1 values (6, 1, 1);
 INSERT into t1 values (10, 1, 1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 values (15, 1, 1);
 
 select * from t1;
@@ -219,7 +219,7 @@ subpartition by hash (a+b)
 
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 VALUES (5,1,1);
 
 SELECT * from t1;
@@ -260,7 +260,7 @@ subpartition by hash (a+b)
 
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 VALUES (5,1,1);
 
 SELECT * from t1;
@@ -301,7 +301,7 @@ subpartition by hash (a+b)
 
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 VALUES (5,1,1);
 
 SELECT * from t1;
@@ -342,7 +342,7 @@ subpartition by hash (a+b)
 
 INSERT into t1 VALUES (1,1,1);
 INSERT into t1 VALUES (4,1,1);
---error 1030
+--error ER_NO_PARTITION_FOR_GIVEN_VALUE
 INSERT into t1 VALUES (5,1,1);
 
 SELECT * from t1;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 650830832cb3d447f631d0f91fe8bd12abc4718b..b0b4ac3fdcdf7b61a3989660525307c018bfcd41 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1174,7 +1174,7 @@ int ha_partition::write_row(byte * buf)
   }
 #endif
   if (unlikely(error))
-    DBUG_RETURN(error);
+    DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
   m_last_part= part_id;
   DBUG_PRINT("info", ("Insert in partition %d", part_id));
   DBUG_RETURN(m_file[part_id]->write_row(buf));
@@ -2973,7 +2973,11 @@ void ha_partition::print_error(int error, myf errflag)
   DBUG_ENTER("ha_partition::print_error");
   /* Should probably look for my own errors first */
   /* monty: needs to be called for the last used partition ! */
-  m_file[0]->print_error(error, errflag);
+  if (error == HA_ERR_NO_PARTITION_FOUND)
+    my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0),
+             m_part_info->part_expr->val_int());
+  else
+    m_file[0]->print_error(error, errflag);
   DBUG_VOID_RETURN;
 }
 
diff --git a/sql/handler.h b/sql/handler.h
index b4b90cbfaa84169c4fdafad7edaac158df7af3c4..5674698487c351730305c1efce8566087d572c29 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -717,6 +717,9 @@ typedef struct st_ha_check_opt
 bool is_partition_in_list(char *part_name, List<char> list_part_names);
 bool is_partitions_in_table(partition_info *new_part_info,
                             partition_info *old_part_info);
+bool check_reorganise_list(partition_info *new_part_info,
+                           partition_info *old_part_info,
+                           List<char> list_part_names);
 bool set_up_defaults_for_partitioning(partition_info *part_info,
                                       handler *file,
                                       ulonglong max_rows,
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index d6be040586577cf33969bfe6a96ed0fa94b0c36d..35b6b17efa477a571f5687d4e233c88c4e4431bc 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5725,3 +5725,5 @@ ER_PLUGIN_IS_NOT_LOADED
 	eng "Plugin '%-.64s' is not loaded"
 ER_WRONG_VALUE
 	eng "Incorrect %-.32s value: '%-.128s'"
+ER_NO_PARTITION_FOR_GIVEN_VALUE
+	eng "Table has no partition for value %d"
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index dd4f2d9246abba0ffb8f73afffabe4586e0788c2..8571e39d9b8b843b4ddbc15d4ec5731405e58a74 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -189,6 +189,61 @@ bool is_partitions_in_table(partition_info *new_part_info,
 }
 
 
+/*
+  Check that the reorganized table will not have duplicate partitions.
+
+  SYNOPSIS
+    check_reorganise_list()
+    new_part_info      New partition info
+    old_part_info      Old partition info
+    list_part_names    The list of partition names that will go away and can be reused in the
+                       new table.
+
+  RETURN VALUES
+    TRUE               Inacceptable name conflict detected.
+    FALSE              New names are OK.
+
+  DESCRIPTION
+    Can handle that the 'new_part_info' and 'old_part_info' the same
+    in which case it checks that the list of names in the partitions
+    doesn't contain any duplicated names.
+*/
+
+bool check_reorganise_list(partition_info *new_part_info,
+                           partition_info *old_part_info,
+                           List<char> list_part_names)
+{
+  uint new_count, old_count;
+  uint no_new_parts= new_part_info->partitions.elements;
+  uint no_old_parts= old_part_info->partitions.elements;
+  List_iterator<partition_element> new_parts_it(new_part_info->partitions);
+  bool same_part_info= (new_part_info == old_part_info);
+  DBUG_ENTER("check_reorganise_list");
+
+  new_count= 0;
+  do
+  {
+    List_iterator<partition_element> old_parts_it(old_part_info->partitions);
+    char *new_name= (new_parts_it++)->partition_name;
+    new_count++;
+    old_count= 0;
+    do
+    {
+      char *old_name= (old_parts_it++)->partition_name;
+      old_count++;
+      if (same_part_info && old_count == new_count)
+        break;
+      if (!(my_strcasecmp(system_charset_info, old_name, new_name)))
+      {
+        if (!is_partition_in_list(old_name, list_part_names))
+          DBUG_RETURN(TRUE);
+      }
+    } while (old_count < no_old_parts);
+  } while (new_count < no_new_parts);
+  DBUG_RETURN(FALSE);
+}
+
+
 /*
   A useful routine used by update_row for partition handlers to calculate
   the partition ids of the old and the new record.
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 275cf847a99b990ad099a1f4f59c745769af93a6..a74a550679f697d92023a76d0a2a309231669ad1 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3832,7 +3832,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
         my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "REORGANISE");
         DBUG_RETURN(TRUE);
       }
-      if (is_partitions_in_table(alt_part_info, tab_part_info))
+      if (check_reorganise_list(alt_part_info, tab_part_info,
+                                alter_info->partition_names))
       {
         my_error(ER_SAME_NAME_PARTITION, MYF(0));
         DBUG_RETURN(TRUE);
@@ -3901,6 +3902,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
       }
     }
     partition_changed= TRUE;
+    tab_part_info->no_parts= tab_part_info->partitions.elements;
     create_info->db_type= DB_TYPE_PARTITION_DB;
     thd->lex->part_info= tab_part_info;
     if (alter_info->flags == ALTER_ADD_PARTITION ||