diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index f622b2d2fb29aef257289698feab732182cfb3ec..097983cbbd303a139ce0b9e10fac6ad30e1a89e6 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1774,6 +1774,7 @@ static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row);
 static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row);
 static int stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row);
 static int stmt_read_row_no_data(MYSQL_STMT *stmt, unsigned char **row);
+static int stmt_read_row_no_result_set(MYSQL_STMT *stmt, unsigned char **row);
 
 /*
   This function is used in mysql_stmt_store_result if
@@ -2036,7 +2037,7 @@ mysql_stmt_init(MYSQL *mysql)
   stmt->list.data= stmt;
   stmt->state= MYSQL_STMT_INIT_DONE;
   stmt->mysql= mysql;
-  stmt->read_row_func= stmt_read_row_no_data;
+  stmt->read_row_func= stmt_read_row_no_result_set;
   stmt->prefetch_rows= DEFAULT_PREFETCH_ROWS;
   /* The rest of statement members was bzeroed inside malloc */
 
@@ -2778,6 +2779,13 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
 static int
 stmt_read_row_no_data(MYSQL_STMT *stmt  __attribute__((unused)),
                       unsigned char **row  __attribute__((unused)))
+{
+  return MYSQL_NO_DATA;
+}
+
+static int
+stmt_read_row_no_result_set(MYSQL_STMT *stmt  __attribute__((unused)),
+                      unsigned char **row  __attribute__((unused)))
 {
   set_stmt_error(stmt, CR_NO_RESULT_SET, unknown_sqlstate);
   return 1;
@@ -4600,7 +4608,8 @@ int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt)
       ((rc= stmt_fetch_row(stmt, row)) && rc != MYSQL_DATA_TRUNCATED))
   {
     stmt->state= MYSQL_STMT_PREPARE_DONE;       /* XXX: this is buggy */
-    stmt->read_row_func= stmt_read_row_no_data;
+    stmt->read_row_func= (rc == MYSQL_NO_DATA) ? 
+      stmt_read_row_no_data : stmt_read_row_no_result_set;
   }
   else
   {
@@ -4937,7 +4946,7 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
       for (; param < param_end; param++)
         param->long_data_used= 0;
     }
-    stmt->read_row_func= stmt_read_row_no_data;
+    stmt->read_row_func= stmt_read_row_no_result_set;
     if (mysql)
     {
       if ((int) stmt->state > (int) MYSQL_STMT_PREPARE_DONE)
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index dd1fb491064a915601deb34d82110584023192b7..4bc2ed0fdc80433688e1f26711e7f78a4c627a86 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -657,3 +657,22 @@ a	b
 1.1	1.100
 2.1	2.100
 DROP TABLE t1;
+create table t1 (utext varchar(20) character set ucs2);
+insert into t1 values ("lily");
+insert into t1 values ("river");
+prepare stmt from 'select utext from t1 where utext like ?';
+set @param1='%%';
+execute stmt using @param1;
+utext
+lily
+river
+execute stmt using @param1;
+utext
+lily
+river
+select utext from t1 where utext like '%%';
+utext
+lily
+river
+drop table t1;
+deallocate prepare stmt;
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 1896db84de057005054038d23766bf895e7ddd01..81d85306e93afa8b21f119517ab3d830c108428f 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -759,25 +759,6 @@ execute stmt using @a, @b;
 ?=?
 1
 deallocate prepare stmt;
-create table t1 (utext varchar(20) character set ucs2);
-insert into t1 values ("lily");
-insert into t1 values ("river");
-prepare stmt from 'select utext from t1 where utext like ?';
-set @param1='%%';
-execute stmt using @param1;
-utext
-lily
-river
-execute stmt using @param1;
-utext
-lily
-river
-select utext from t1 where utext like '%%';
-utext
-lily
-river
-drop table t1;
-deallocate prepare stmt;
 create table t1 (a int);
 prepare stmt from "select ??";
 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 '?' at line 1
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 74c03987a6ac126ec7434d54d28d8c37eb755ebb..345de49c21ddcc1b689b49636752e0f93122d6b7 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -3062,4 +3062,21 @@ l
 drop procedure bug6063|
 drop procedure bug7088_1|
 drop procedure bug7088_2|
+drop procedure if exists bug9565_sub|
+drop procedure if exists bug9565|
+create procedure bug9565_sub()
+begin
+select * from t1;
+end|
+create procedure bug9565()
+begin
+insert into t1 values ("one", 1);
+call bug9565_sub();
+end|
+call bug9565()|
+id	data
+one	1
+delete from t1|
+drop procedure bug9565_sub|
+drop procedure bug9565|
 drop table t1,t2;
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index d7ad803b82853ff364300d00ed4bcf42fed94ae2..adc22cd1ac2c00b8d0ca483ec9aec722930fa23b 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -1235,3 +1235,13 @@ create table t1(a varchar(65537));
 ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
 create table t1(a varbinary(65537));
 ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead
+set @@sql_mode='traditional';
+create table t1(a int, b date not null);
+alter table t1 modify a bigint unsigned not null;
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` bigint(20) unsigned NOT NULL,
+  `b` date NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index ef40a408932a19dc260cd2a7c4c377a8362d77d0..684c4950acdbb28574092b1ef4326ff135cbfaa2 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -1977,3 +1977,17 @@ A
 B
 DROP VIEW v1;
 DROP TABLE t1;
+CREATE TABLE t1 ( bug_table_seq   INTEGER NOT NULL);
+CREATE OR REPLACE VIEW v1 AS SELECT * from t1;
+DROP PROCEDURE IF EXISTS p1;
+Warnings:
+Note	1305	PROCEDURE p1 does not exist
+CREATE PROCEDURE p1 ( )
+BEGIN
+DO (SELECT  @next := IFNULL(max(bug_table_seq),0) + 1 FROM v1);
+INSERT INTO t1 VALUES (1);
+END //
+CALL p1();
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index f4327536795be1cf6b7293ee6b661d6a2289809b..d032c1249dfb41a0ed7c58c5d794dff121fdb33d 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -427,3 +427,17 @@ INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0);
 update t1 set b=a;
 SELECT * FROM t1;
 DROP TABLE t1;
+
+#
+# Bug#9442 Set parameter make query fail if column character set is UCS2
+#
+create table t1 (utext varchar(20) character set ucs2);
+insert into t1 values ("lily");
+insert into t1 values ("river");
+prepare stmt from 'select utext from t1 where utext like ?';
+set @param1='%%';
+execute stmt using @param1;
+execute stmt using @param1;
+select utext from t1 where utext like '%%';
+drop table t1;
+deallocate prepare stmt;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index fa5dd0680b5cf91943359dc8d8f5365e3e499294..e8ea1dc373b7a6d7faafa7c410b910fa6f057fc8 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -789,19 +789,6 @@ set @b='CHRISTINE';
 execute stmt using @a, @b;
 deallocate prepare stmt;
 #
-# Bug#9442 Set parameter make query fail if column character set is UCS2
-#
-create table t1 (utext varchar(20) character set ucs2);
-insert into t1 values ("lily");
-insert into t1 values ("river");
-prepare stmt from 'select utext from t1 where utext like ?';
-set @param1='%%';
-execute stmt using @param1;
-execute stmt using @param1;
-select utext from t1 where utext like '%%';
-drop table t1;
-deallocate prepare stmt;
-#
 # Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops
 # replication": check that errouneous queries with placeholders are not
 # allowed
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 4df49c5f93446378466251557c3b0dfd42fd05c4..13de2090a848bcd0d10ddbf4047a23881284600e 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -3832,6 +3832,28 @@ drop procedure bug6063|
 drop procedure bug7088_1|
 drop procedure bug7088_2|
 
+#
+# BUG#9565: "Wrong locking in stored procedure if a sub-sequent procedure
+#           is called".
+#
+--disable_warnings
+drop procedure if exists bug9565_sub|
+drop procedure if exists bug9565|
+--enable_warnings
+create procedure bug9565_sub()
+begin
+  select * from t1;
+end|
+create procedure bug9565()
+begin
+  insert into t1 values ("one", 1);
+  call bug9565_sub();
+end|
+call bug9565()|
+delete from t1|
+drop procedure bug9565_sub|
+drop procedure bug9565|
+
 
 #
 # BUG#NNNN: New bug synopsis
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index 302acc9bef2268e8aea5bf623f769b5545eb89ea..6ac88e4d6297241852da0702a8a49d38ee6b4ddf 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -1093,3 +1093,13 @@ set @@sql_mode='traditional';
 create table t1(a varchar(65537));
 --error 1074
 create table t1(a varbinary(65537));
+
+#
+# Bug #9881: problem with altering table
+#
+
+set @@sql_mode='traditional';
+create table t1(a int, b date not null);                                       
+alter table t1 modify a bigint unsigned not null;
+show create table t1;
+drop table t1;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index d296d5ebee5ac98a1ab08a4e1e26caa708b30fd2..8eeac41efcd7aa5b4263cde09d94a5a0d1eab4a6 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -1804,7 +1804,6 @@ drop table t1;
 #
 # Test for bug #11771: wrong query_id in SELECT * FROM <view>
 #
-
 CREATE TABLE t1 (f1 char) ENGINE = innodb;
 INSERT INTO t1 VALUES ('A');
 CREATE VIEW  v1 AS SELECT * FROM t1;
@@ -1815,3 +1814,21 @@ SELECT * FROM t1;
 
 DROP VIEW v1;
 DROP TABLE t1;
+
+#
+# opening table in correct locking mode (BUG#9597)
+#
+CREATE TABLE t1 ( bug_table_seq   INTEGER NOT NULL);
+CREATE OR REPLACE VIEW v1 AS SELECT * from t1;
+DROP PROCEDURE IF EXISTS p1;
+delimiter //;
+CREATE PROCEDURE p1 ( )
+BEGIN
+        DO (SELECT  @next := IFNULL(max(bug_table_seq),0) + 1 FROM v1);
+        INSERT INTO t1 VALUES (1);
+END //
+delimiter ;//
+CALL p1();
+DROP PROCEDURE p1;
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/sql/field.cc b/sql/field.cc
index 58844db2f38eeeeb08b8b940776b8abe0a8707aa..1a3b0f704981a413b3376fb2a2a992c1709908b7 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -8488,7 +8488,8 @@ create_field::create_field(Field *old_field,Field *orig_field)
   else
     interval=0;
   def=0;
-  if (!old_field->is_real_null() && ! (flags & BLOB_FLAG) &&
+  if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) &&
+      !old_field->is_real_null() &&
       old_field->ptr && orig_field)
   {
     char buff[MAX_FIELD_WIDTH],*pos;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 367dc3bb0f62ce5fa48a1328dd0fa2676fc869a7..0013d478600486bafd6fece35e3b2b174c163e2a 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1041,6 +1041,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
 
   if (thd->locked_tables || thd->prelocked_mode)
   {						// Using table locks
+    TABLE *best_table= 0;
+    int best_distance= INT_MIN, distance;
     for (table=thd->open_tables; table ; table=table->next)
     {
       if (table->s->key_length == key_length &&
@@ -1049,11 +1051,37 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
           table->query_id != thd->query_id && /* skip tables already used by this query */
           !(thd->prelocked_mode && table->query_id))
       {
-        table->query_id= thd->query_id;
-        DBUG_PRINT("info",("Using locked table"));
-	goto reset;
+        distance= ((int) table->reginfo.lock_type -
+                   (int) table_list->lock_type);
+        /*
+          Find a table that either has the exact lock type requested,
+          or has the best suitable lock. In case there is no locked
+          table that has an equal or higher lock than requested,
+          we still maitain the best_table to produce an error message
+          about wrong lock mode on the table. The best_table is changed
+          if bd < 0 <= d or bd < d < 0 or 0 <= d < bd.
+
+          distance <  0 - we have not enough high lock mode
+          distance >  0 - we have lock mode higher then we require
+          distance == 0 - we have lock mode exactly which we need
+        */
+        if (best_distance < 0 && distance > best_distance ||
+            distance >= 0 && distance < best_distance)
+        {
+          best_distance= distance;
+          best_table= table;
+          if (best_distance == 0)
+            break;
+        }
       }
     }
+    if (best_table)
+    {
+      table= best_table;
+      table->query_id= thd->query_id;
+      DBUG_PRINT("info",("Using locked table"));
+      goto reset;
+    }
     /*
       is it view?
       (it is work around to allow to open view with locked tables,
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 44f126d96ec8c6c7cc2aa1a22802c22b6c97d5e0..37bfd1656a82f3bb1d708671746055b67b6c892b 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1170,12 +1170,22 @@ public:
     This is to track items changed during execution of a prepared
     statement/stored procedure. It's created by
     register_item_tree_change() in memory root of THD, and freed in
-    rollback_item_tree_changes(). For conventional execution it's always 0.
+    rollback_item_tree_changes(). For conventional execution it's always
+    empty.
   */
   Item_change_list change_list;
 
   /*
-    Current prepared Query_arena if there one, or 0
+    A permanent memory area of the statement. For conventional
+    execution, the parsed tree and execution runtime reside in the same
+    memory root. In this case current_arena points to THD. In case of
+    a prepared statement or a stored procedure statement, thd->mem_root
+    conventionally points to runtime memory, and thd->current_arena
+    points to the memory of the PS/SP, where the parsed tree of the
+    statement resides. Whenever you need to perform a permanent
+    transformation of a parsed tree, you should allocate new memory in
+    current_arena, to allow correct re-execution of PS/SP.
+    Note: in the parser, current_arena == thd, even for PS/SP.
   */
   Query_arena *current_arena;
   /*
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index a056814a1531caf5ac37dba80659d2ebd0abba29..010f467c4ad0a02061124ebd7d851cc2e921efad 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -13315,7 +13315,7 @@ static void test_bug9992()
   DIE_UNLESS(rc == 1);                         /* Got errors, as expected */
 
   if (!opt_silent)
-    fprintf(stdout, "Got error, sa expected:\n [%d] %s\n",
+    fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
             mysql_errno(mysql1), mysql_error(mysql1));
 
   mysql_close(mysql1);
@@ -13705,6 +13705,51 @@ static void test_bug11183()
   myquery(rc);
 }
 
+static void test_bug11037()
+{
+  MYSQL_STMT *stmt;
+  int rc;
+  const char *stmt_text;
+
+  myheader("test_bug11037");
+
+  mysql_query(mysql, "drop table if exists t1");
+
+  rc= mysql_query(mysql, "create table t1 (id int not null)");
+  myquery(rc);
+
+  rc= mysql_query(mysql, "insert into t1 values (1)");
+  myquery(rc);
+
+  stmt_text= "select id FROM t1";
+  stmt= mysql_stmt_init(mysql);
+  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
+
+  /* expected error */
+  rc = mysql_stmt_fetch(stmt);
+  DIE_UNLESS(rc==1);
+  if (!opt_silent)
+    fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
+            mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
+
+  rc = mysql_stmt_execute(stmt);
+  check_execute(stmt, rc);
+
+  rc = mysql_stmt_fetch(stmt);
+  DIE_UNLESS(rc==0);
+
+  rc = mysql_stmt_fetch(stmt);
+  DIE_UNLESS(rc==MYSQL_NO_DATA);
+
+  rc = mysql_stmt_fetch(stmt);
+  DIE_UNLESS(rc==MYSQL_NO_DATA);
+
+  mysql_stmt_close(stmt);
+  rc= mysql_query(mysql, "drop table t1");
+  myquery(rc);
+}
+
+
 /*
   Read and parse arguments and MySQL options from my.cnf
 */
@@ -13948,6 +13993,7 @@ static struct my_tests_st my_tests[]= {
   { "test_bug10214", test_bug10214 },
   { "test_bug9735", test_bug9735 },
   { "test_bug11183", test_bug11183 },
+  { "test_bug11037", test_bug11037 },
   { 0, 0 }
 };