diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 1e62e5e641d8a458aac1de42e4df1ed2ab3a26cc..301becf9c62815245f7e0db63785041ab5cc6b28 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -1153,9 +1153,12 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
 	      /* We don't need to lock the key tree here as we don't allow
 		 concurrent threads when running myisamchk
 	      */
-              int search_result= (keyinfo->flag & HA_SPATIAL) ?
+              int search_result=
+#ifdef HAVE_RTREE_KEYS
+                (keyinfo->flag & HA_SPATIAL) ?
                 rtree_find_first(info, key, info->lastkey, key_length,
                                  MBR_EQUAL | MBR_DATA) : 
+#endif
                 _mi_search(info,keyinfo,info->lastkey,key_length,
                            SEARCH_SAME, info->s->state.key_root[key]);
               if (search_result)
@@ -1366,7 +1369,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
 			   param->temp_filename);
       goto err;
     }
-    if (filecopy(param,new_file,info->dfile,0L,new_header_length,
+    if (new_header_length &&
+        filecopy(param,new_file,info->dfile,0L,new_header_length,
 		 "datafile-header"))
       goto err;
     info->s->state.dellink= HA_OFFSET_ERROR;
@@ -2063,7 +2067,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
 			   param->temp_filename);
       goto err;
     }
-    if (filecopy(param, new_file,info->dfile,0L,new_header_length,
+    if (new_header_length &&
+        filecopy(param, new_file,info->dfile,0L,new_header_length,
 		 "datafile-header"))
       goto err;
     if (param->testflag & T_UNPACK)
@@ -2431,7 +2436,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
 			   param->temp_filename);
       goto err;
     }
-    if (filecopy(param, new_file,info->dfile,0L,new_header_length,
+    if (new_header_length &&
+        filecopy(param, new_file,info->dfile,0L,new_header_length,
 		 "datafile-header"))
       goto err;
     if (param->testflag & T_UNPACK)
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 24a4ca9a85f96d7aa750fdde2e31f1d7e24e8f66..642a0fc13b516b4b9233ee0ee68c91dcd1b95e06 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -747,6 +747,27 @@ select export_set(5, name, upper(name), ",", 5) from bug20536;
 export_set(5, name, upper(name), ",", 5)
 test1,TEST1,test1,TEST1,TEST1
 'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2'
+CREATE TABLE t1 (
+status enum('active','passive') collate latin1_general_ci 
+NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `status` enum('active','passive') character set latin1 collate latin1_general_ci NOT NULL default 'passive'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 ADD a int NOT NULL AFTER status;
+CREATE TABLE t2 (
+status enum('active','passive') collate ucs2_turkish_ci 
+NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `status` enum('active','passive') character set ucs2 collate ucs2_turkish_ci NOT NULL default 'passive'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t2 ADD a int NOT NULL AFTER status;
+DROP TABLE t1,t2;
 select password(name) from bug20536;
 password(name)
 ????????????????????
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 01aa4ddf85931772c6d50882f80e990bd647e488..78752622db7ce5df79124f341cd899c22abdb5fa 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -889,3 +889,50 @@ create temporary table if not exists t1 (a1 int);
 execute stmt;
 drop temporary table t1;
 deallocate prepare stmt;
+CREATE TABLE t1(
+ID int(10) unsigned NOT NULL auto_increment,
+Member_ID varchar(15) NOT NULL default '',
+Action varchar(12) NOT NULL,
+Action_Date datetime NOT NULL,
+Track varchar(15) default NULL,
+User varchar(12) default NULL,
+Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
+CURRENT_TIMESTAMP,
+PRIMARY KEY (ID),
+KEY Action (Action),
+KEY Action_Date (Action_Date)
+);
+INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
+('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
+('111111', 'Enrolled', '2006-03-01', 'CAD' ),
+('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
+('222222', 'Enrolled', '2006-03-07', 'CAD' ),
+('222222', 'Enrolled', '2006-03-07', 'CHF' ),
+('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
+('333333', 'Enrolled', '2006-03-01', 'CAD' ),
+('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
+('444444', 'Enrolled', '2006-03-01', 'CAD' ),
+('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
+('555555', 'Enrolled', '2006-07-21', 'CAD' ),
+('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
+('666666', 'Enrolled', '2006-02-09', 'CAD' ),
+('666666', 'Enrolled', '2006-05-12', 'CHF' ),
+('666666', 'Disenrolled', '2006-06-01', 'CAD' );
+PREPARE STMT FROM
+"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
+  WHERE Member_ID=? AND Action='Enrolled' AND
+        (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
+                                  WHERE Member_ID=?
+                                    GROUP BY Track 
+                                      HAVING Track>='CAD' AND
+                                             MAX(Action_Date)>'2006-03-01')";
+SET @id='111111';
+EXECUTE STMT USING @id,@id;
+GROUP_CONCAT(Track SEPARATOR ', ')
+NULL
+SET @id='222222';
+EXECUTE STMT USING @id,@id;
+GROUP_CONCAT(Track SEPARATOR ', ')
+CAD
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index ba4de7f6406c0f3fcd8cc7644923db8ecb53fe81..ad847b5f1569aea52c90a4d39272e7b2e87d8b28 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -2946,3 +2946,39 @@ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
 a	a	b
 10	1	359
 drop table t1,t2;
+CREATE TABLE t1 (                  
+field1 int NOT NULL,                 
+field2 int NOT NULL,                 
+field3 int NOT NULL,                 
+PRIMARY KEY  (field1,field2,field3)  
+);
+CREATE TABLE t2 (             
+fieldA int NOT NULL,            
+fieldB int NOT NULL,            
+PRIMARY KEY  (fieldA,fieldB)     
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1	field2	COUNT(*)
+1	1	2
+1	2	3
+1	3	1
+SELECT field1, field2
+FROM  t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB 
+FROM t2 WHERE fieldA = field1);
+field1	field2
+1	2
+SELECT field1, field2
+FROM  t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB 
+FROM t2 WHERE fieldA = field1);
+field1	field2
+1	1
+1	3
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index d96b9938f1bb967d66654829f9d7eb0c897aa854..641080f48ab1054063aa9ba821df9d48a21531fe 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -482,6 +482,27 @@ select make_set(3, name, upper(name)) from bug20536;
 select export_set(5, name, upper(name)) from bug20536;
 select export_set(5, name, upper(name), ",", 5) from bug20536;
 
+#
+# Bug #20108: corrupted default enum value for a ucs2 field              
+#
+
+CREATE TABLE t1 (
+  status enum('active','passive') collate latin1_general_ci 
+    NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 ADD a int NOT NULL AFTER status; 
+
+CREATE TABLE t2 (
+  status enum('active','passive') collate ucs2_turkish_ci 
+    NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t2;
+ALTER TABLE t2 ADD a int NOT NULL AFTER status; 
+
+DROP TABLE t1,t2;
+
+
 # Some broken functions:  add these tests just to document current behavior.
 
 # PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 0ca293eb1baeaa96f0555407583dafcbc52f8491..7c2a42404adff22879f4c77d6f3e947915ec1ad5 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -951,4 +951,56 @@ execute stmt;
 drop temporary table t1;
 deallocate prepare stmt;
 
+#
+# BUG#22085: Crash on the execution of a prepared statement that
+#            uses an IN subquery with aggregate functions in HAVING 
+#
+
+CREATE TABLE t1(
+  ID int(10) unsigned NOT NULL auto_increment,
+  Member_ID varchar(15) NOT NULL default '',
+  Action varchar(12) NOT NULL,
+  Action_Date datetime NOT NULL,
+  Track varchar(15) default NULL,
+  User varchar(12) default NULL,
+  Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
+    CURRENT_TIMESTAMP,
+  PRIMARY KEY (ID),
+  KEY Action (Action),
+  KEY Action_Date (Action_Date)
+);
+
+INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
+  ('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
+  ('111111', 'Enrolled', '2006-03-01', 'CAD' ),
+  ('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
+  ('222222', 'Enrolled', '2006-03-07', 'CAD' ),
+  ('222222', 'Enrolled', '2006-03-07', 'CHF' ),
+  ('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
+  ('333333', 'Enrolled', '2006-03-01', 'CAD' ),
+  ('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
+  ('444444', 'Enrolled', '2006-03-01', 'CAD' ),
+  ('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
+  ('555555', 'Enrolled', '2006-07-21', 'CAD' ),
+  ('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
+  ('666666', 'Enrolled', '2006-02-09', 'CAD' ),
+  ('666666', 'Enrolled', '2006-05-12', 'CHF' ),
+  ('666666', 'Disenrolled', '2006-06-01', 'CAD' );
+
+PREPARE STMT FROM
+"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
+  WHERE Member_ID=? AND Action='Enrolled' AND
+        (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
+                                  WHERE Member_ID=?
+                                    GROUP BY Track 
+                                      HAVING Track>='CAD' AND
+                                             MAX(Action_Date)>'2006-03-01')";
+SET @id='111111';
+EXECUTE STMT USING @id,@id;
+SET @id='222222';
+EXECUTE STMT USING @id,@id;
+
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+
 # End of 4.1 tests
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 1018b5de005e863984821b4d1d170e5639cb481d..6defa8b16a53aa1191d6d2c5d6db29d439ca476c 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1911,4 +1911,41 @@ SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
 
 drop table t1,t2;
 
+#
+# Bug #21853: assert failure for a grouping query with
+#             an ALL/ANY quantified subquery in HAVING 
+#
+
+CREATE TABLE t1 (                  
+  field1 int NOT NULL,                 
+  field2 int NOT NULL,                 
+  field3 int NOT NULL,                 
+  PRIMARY KEY  (field1,field2,field3)  
+);
+CREATE TABLE t2 (             
+  fieldA int NOT NULL,            
+  fieldB int NOT NULL,            
+  PRIMARY KEY  (fieldA,fieldB)     
+); 
+
+INSERT INTO t1 VALUES
+  (1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+
+SELECT field1, field2, COUNT(*)
+  FROM t1 GROUP BY field1, field2;
+
+SELECT field1, field2
+  FROM  t1
+    GROUP BY field1, field2
+      HAVING COUNT(*) >= ALL (SELECT fieldB 
+                                FROM t2 WHERE fieldA = field1);
+SELECT field1, field2
+  FROM  t1
+    GROUP BY field1, field2
+      HAVING COUNT(*) < ANY (SELECT fieldB 
+                               FROM t2 WHERE fieldA = field1);
+
+DROP TABLE t1, t2;
+
 # End of 4.1 tests
diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c
index cf26428d65fe283c31f5ad134795176dc88eb1f0..efc199271831b9a961b074e6a36388dee551dbd3 100644
--- a/mysys/my_chsize.c
+++ b/mysys/my_chsize.c
@@ -44,7 +44,9 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
   DBUG_PRINT("my",("fd: %d  length: %lu  MyFlags: %d",fd,(ulong) newlength,
 		   MyFlags));
 
-  oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE));
+  if ((oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength)
+    DBUG_RETURN(0);
+
   DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
 
   if (oldsize > newlength)
diff --git a/sql/field.h b/sql/field.h
index a33cb0a93aae6316ad411f05d444e62413f6ac35..79fb7ff76d1608da318d0dbc2a3af67a12cf1bcd 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1192,6 +1192,8 @@ class create_field :public Sql_alloc {
   uint decimals,flags,pack_length;
   Field::utype unireg_check;
   TYPELIB *interval;			// Which interval to use
+  TYPELIB *save_interval;               // Temporary copy for the above
+                                        // Used only for UCS2 intervals
   List<String> interval_list;
   CHARSET_INFO *charset;
   Field::geometry_type geom_type;
diff --git a/sql/item.cc b/sql/item.cc
index 7c9f6ec77fb43c813ffbcafe0cbc452a1488c618..94f0a24fcc322d6a65ccd0229cd9748dd5f4adbf 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -387,6 +387,7 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
   }
   else if ((type() == SUM_FUNC_ITEM ||
             (used_tables() & ~PARAM_TABLE_BIT)) &&
+           type() != SUBSELECT_ITEM &&
            type() != REF_ITEM)
   {
     /*
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 02ec7ae08edf6e36666b49a1ce4eece808ef37af..74a9fc573c406a029123c4612e760df2de605fd9 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -290,8 +290,6 @@ JOIN::prepare(Item ***rref_pointer_array,
     select_lex->having_fix_field= 0;
     if (having_fix_rc || thd->net.report_error)
       DBUG_RETURN(-1);				/* purecov: inspected */
-    if (having->with_sum_func)
-      having->split_sum_func2(thd, ref_pointer_array, all_fields, &having);
   }
 
   // Is it subselect
@@ -306,6 +304,9 @@ JOIN::prepare(Item ***rref_pointer_array,
     }
   }
 
+  if (having && having->with_sum_func)
+    having->split_sum_func2(thd, ref_pointer_array, all_fields, &having);
+
   if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
     DBUG_RETURN(-1);
   
diff --git a/sql/unireg.cc b/sql/unireg.cc
index e3bf763f700a5097523c6570f03bb548464bda6e..e4fdc77912c1f7988e4b659bbeaca44c595b7d82 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -190,13 +190,19 @@ bool mysql_create_frm(THD *thd, my_string file_name,
     goto err3;
 
   {
-    /* Unescape all UCS2 intervals: were escaped in pack_headers */
+    /* 
+      Restore all UCS2 intervals.
+      HEX representation of them is not needed anymore.
+    */
     List_iterator<create_field> it(create_fields);
     create_field *field;
     while ((field=it++))
     {
-      if (field->interval && field->charset->mbminlen > 1)
-        unhex_type2(field->interval);
+      if (field->save_interval)
+      {
+        field->interval= field->save_interval;
+        field->save_interval= 0;
+      }
     }
   }
   DBUG_RETURN(0);
@@ -452,18 +458,36 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
       reclength=(uint) (field->offset+ data_offset + length);
     n_length+= (ulong) strlen(field->field_name)+1;
     field->interval_id=0;
+    field->save_interval= 0;
     if (field->interval)
     {
       uint old_int_count=int_count;
 
       if (field->charset->mbminlen > 1)
       {
-        /* Escape UCS2 intervals using HEX notation */
+        /* 
+          Escape UCS2 intervals using HEX notation to avoid
+          problems with delimiters between enum elements.
+          As the original representation is still needed in 
+          the function make_empty_rec to create a record of
+          filled with default values it is saved in save_interval
+          The HEX representation is created from this copy.
+        */
+        field->save_interval= field->interval;
+        field->interval= (TYPELIB*) sql_alloc(sizeof(TYPELIB));
+        *field->interval= *field->save_interval; 
+        field->interval->type_names= 
+          (const char **) sql_alloc(sizeof(char*) * 
+				    (field->interval->count+1));
+        field->interval->type_names[field->interval->count]= 0;
+        field->interval->type_lengths=
+          (uint *) sql_alloc(sizeof(uint) * field->interval->count);
+ 
         for (uint pos= 0; pos < field->interval->count; pos++)
         {
           char *dst;
-          uint length= field->interval->type_lengths[pos], hex_length;
-          const char *src= field->interval->type_names[pos];
+          uint length= field->save_interval->type_lengths[pos], hex_length;
+          const char *src= field->save_interval->type_names[pos];
           const char *srcend= src + length;
           hex_length= length * 2;
           field->interval->type_lengths[pos]= hex_length;
@@ -715,7 +739,8 @@ static bool make_empty_rec(File file,enum db_type table_type,
 			       field->charset,
 			       field->geom_type,
 			       field->unireg_check,
-			       field->interval,
+			       field->save_interval ? field->save_interval :
+                               field->interval, 
 			       field->field_name,
 			       &table);