diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 5758f5b93d7ed37217c033408998f544a1d429e2..3446babbb52e7e2fdc9333fdcb3db140cab12206 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2111,4 +2111,21 @@ SET @bug51650 = 1;
 INSERT IGNORE INTO t2 SET a = '777';
 DROP TRIGGER trg1;
 DROP TABLE t1, t2;
+CREATE TABLE t1 (id INT NOT NULL);
+CREATE TABLE t2 (id INT NOT NULL);
+INSERT t1 VALUES (1),(2),(3);
+UPDATE t1 SET id=NULL;
+Warnings:
+Warning	1048	Column 'id' cannot be null
+Warning	1048	Column 'id' cannot be null
+Warning	1048	Column 'id' cannot be null
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+INSERT INTO t2 VALUES (3);
+UPDATE t1 SET id=NULL;
+Warnings:
+Warning	1048	Column 'id' cannot be null
+Warning	1048	Column 'id' cannot be null
+Warning	1048	Column 'id' cannot be null
+DROP TRIGGER t1_bu;
+DROP TABLE t1,t2;
 End of 5.1 tests.
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index 2ab8fa9ba1e3f5163e2a72abe24fcc822503d975..368271f1fb2dacb83d68fd6c5ee6ae1c1b4b3091 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2426,4 +2426,17 @@ INSERT IGNORE INTO t2 SET a = '777';
 DROP TRIGGER trg1;
 DROP TABLE t1, t2;
 
+#
+# Bug #48525: trigger changes "Column 'id' cannot be null" behaviour
+#
+CREATE TABLE t1 (id INT NOT NULL);
+CREATE TABLE t2 (id INT NOT NULL);
+INSERT t1 VALUES (1),(2),(3);
+UPDATE t1 SET id=NULL;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+  INSERT INTO t2 VALUES (3);
+UPDATE t1 SET id=NULL;
+DROP TRIGGER t1_bu;
+DROP TABLE t1,t2;
+
 --echo End of 5.1 tests.
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 3574534722ec3b95be29224f4dd7f369ed9a9371..0bffde9671ad84c3ffe49255216cccc3123fdb93 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -122,13 +122,18 @@ set_field_to_null(Field *field)
     return 0;
   }
   field->reset();
-  if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
-  {
+  switch (field->table->in_use->count_cuted_fields) {
+  case CHECK_FIELD_WARN:
     field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
+    /* fall through */
+  case CHECK_FIELD_IGNORE:
     return 0;
+  case CHECK_FIELD_ERROR_FOR_NULL:
+    if (!field->table->in_use->no_errors)
+      my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+    return -1;
   }
-  if (!field->table->in_use->no_errors)
-    my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+  DBUG_ASSERT(0); // impossible
   return -1;
 }
 
@@ -178,13 +183,18 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
     field->table->auto_increment_field_not_null= FALSE;
     return 0;				  // field is set in fill_record()
   }
-  if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
-  {
+  switch (field->table->in_use->count_cuted_fields) {
+  case CHECK_FIELD_WARN:
     field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
+    /* fall through */
+  case CHECK_FIELD_IGNORE:
     return 0;
+  case CHECK_FIELD_ERROR_FOR_NULL:
+    if (!field->table->in_use->no_errors)
+      my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+    return -1;
   }
-  if (!field->table->in_use->no_errors)
-    my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
+  DBUG_ASSERT(0); // impossible
   return -1;
 }
 
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 8a626cabd90c6c941b97a215e359318d7f1c3d07..11d5e5f830b76a5eb4e3180a76d990ed5ce8fab3 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -3009,6 +3009,7 @@ int
 sp_instr_set_trigger_field::execute(THD *thd, uint *nextp)
 {
   DBUG_ENTER("sp_instr_set_trigger_field::execute");
+  thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
   DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this));
 }
 
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 673fc9b78e6a50a7be226a60cf8eb9a4164053c9..266064f9f08fb8b78c62649fdd3f135d86ee0615 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3100,6 +3100,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
   }
 #endif
   
+  backup->count_cuted_fields= count_cuted_fields;
   backup->options=         options;
   backup->in_sub_stmt=     in_sub_stmt;
   backup->enable_slow_log= enable_slow_log;
@@ -3137,6 +3138,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
 
 void THD::restore_sub_statement_state(Sub_statement_state *backup)
 {
+  DBUG_ENTER("THD::restore_sub_statement_state");
 #ifndef EMBEDDED_LIBRARY
   /* BUG#33029, if we are replicating from a buggy master, restore
      auto_inc_intervals_forced so that the top statement can use the
@@ -3163,6 +3165,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
     /* ha_release_savepoint() never returns error. */
     (void)ha_release_savepoint(this, sv);
   }
+  count_cuted_fields= backup->count_cuted_fields;
   transaction.savepoints= backup->savepoints;
   options=          backup->options;
   in_sub_stmt=      backup->in_sub_stmt;
@@ -3192,6 +3195,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
   */
   examined_row_count+= backup->examined_row_count;
   cuted_fields+=       backup->cuted_fields;
+  DBUG_VOID_RETURN;
 }
 
 
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 032985dc44eb5a5375a3883144e3040d94405c86..2ddd935838293a858a66563cf6b0d678fc5e9e83 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -995,6 +995,7 @@ class Sub_statement_state
   bool enable_slow_log;
   bool last_insert_id_used;
   SAVEPOINT *savepoints;
+  enum enum_check_fields count_cuted_fields;
 };
 
 
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 1f4ca90157f25a5b9f67106990e86881a4c61ab0..35c24e7571e652a8ed6b24ba5510d92af89b17a9 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -3158,7 +3158,7 @@ bool select_insert::send_data(List<Item> &values)
 
   thd->count_cuted_fields= CHECK_FIELD_WARN;	// Calculate cuted fields
   store_values(values);
-  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
+  thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
   if (thd->is_error())
   {
     table->auto_increment_field_not_null= FALSE;