List:Commits« Previous MessageNext Message »
From:Alexander Nozdrin Date:October 4 2012 3:22pm
Subject:bzr push into mysql-trunk branch (alexander.nozdrin:4223 to 4232)
View as plain text  
 4232 Alexander Nozdrin	2012-10-04
      Review: polishing.

    modified:
      sql/field.cc
      sql/field.h
      sql/sql_base.cc
      sql/sql_insert.cc
      sql/sql_load.cc
      sql/sql_trigger.cc
 4231 Alexander Nozdrin	2012-10-04
      Review: polishing.

    modified:
      sql/sql_base.cc
      sql/sql_base.h
      sql/sql_load.cc
      sql/table.h
 4230 Alexander Nozdrin	2012-10-04
      Review: fix REPLACE; enhance tests.

    modified:
      mysql-test/r/wl6030.result
      mysql-test/t/wl6030.test
      sql/sql_base.cc
 4229 Alexander Nozdrin	2012-10-04
      Review: polishing.

    modified:
      sql/sql_insert.cc
      sql/sql_load.cc
      sql/sql_trigger.cc
 4228 Alexander Nozdrin	2012-10-04
      Review: cleanup_after_error() -> mysql_insert_cleanup_after_error().

    modified:
      sql/sql_insert.cc
 4227 Alexander Nozdrin	2012-10-04
      Review: polishing.

    modified:
      sql/sql_insert.cc
 4226 Alexander Nozdrin	2012-10-04
      Review: reverting 4201 from trunk-dshulga (select_insert and select_create change).

    modified:
      sql/sql_class.h
      sql/sql_insert.h
 4225 Alexander Nozdrin	2012-10-04
      Review: Polishing field.h/field.cc

    modified:
      sql/field.cc
      sql/field.h
 4224 Alexander Nozdrin	2012-10-04
      Review: Field::field_warning_was_pushed -> m_warnings_pushed.

    modified:
      sql/field.cc
      sql/field.h
 4223 Dmitry Shulga	2012-10-03
      The test related to warnings count was changed in mysql_client_test.c

    modified:
      tests/mysql_client_test.c
=== modified file 'mysql-test/r/wl6030.result'
--- a/mysql-test/r/wl6030.result	2012-10-02 05:35:46 +0000
+++ b/mysql-test/r/wl6030.result	2012-10-04 15:09:30 +0000
@@ -26,6 +26,21 @@ a	b	c
 
 DELETE FROM t1;
 
+# Single REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (NULL, 2, 3);
+REPLACE INTO t1(a, b, c) VALUES (NULL, 20, 30);
+REPLACE INTO t1(b, c) VALUES (200, 300);
+REPLACE INTO t1(a) VALUES (NULL);
+
+SELECT * FROM t1;
+a	b	c
+1	2	3
+1	20	30
+1	200	300
+1	NULL	NULL
+
+DELETE FROM t1;
+
 # Multi INSERT ... VALUES.
 INSERT INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
 INSERT INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
@@ -49,6 +64,29 @@ a	b	c
 
 DELETE FROM t1;
 
+# Multi REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+REPLACE INTO t1(a) VALUES (-3), (NULL), (NULL);
+
+SELECT * FROM t1;
+a	b	c
+1	2	3
+1	20	30
+1	200	300
+1	2	3
+1	20	30
+1	200	300
+1	2	3
+1	20	30
+1	200	300
+1	NULL	NULL
+1	NULL	NULL
+1	NULL	NULL
+
+DELETE FROM t1;
+
 # INSERT ... SELECT.
 INSERT INTO t1 SELECT * FROM t2;
 INSERT INTO t1(a, b, c) SELECT * FROM t2;
@@ -71,6 +109,29 @@ a	b	c
 1	NULL	NULL
 
 DELETE FROM t1;
+
+# REPLACE ... SELECT.
+REPLACE INTO t1 SELECT * FROM t2;
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+REPLACE INTO t1(a) SELECT a FROM t2;
+
+SELECT * FROM t1;
+a	b	c
+1	2	3
+1	20	30
+1	200	300
+1	2	3
+1	20	30
+1	200	300
+1	2	3
+1	20	30
+1	200	300
+1	NULL	NULL
+1	NULL	NULL
+1	NULL	NULL
+
+DELETE FROM t1;
 DELETE FROM t2;
 DROP TRIGGER t1_bi;
 
@@ -95,6 +156,21 @@ a	b	c
 
 DELETE FROM t1;
 
+# Single REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (1, 2, 3);
+ERROR 23000: Column 'a' cannot be null
+REPLACE INTO t1(a, b, c) VALUES (1, 2, 3);
+ERROR 23000: Column 'a' cannot be null
+REPLACE INTO t1(b, c) VALUES (2, 3);
+ERROR 23000: Column 'a' cannot be null
+REPLACE INTO t1(a) VALUES (1);
+ERROR 23000: Column 'a' cannot be null
+
+SELECT * FROM t1;
+a	b	c
+
+DELETE FROM t1;
+
 # Multi INSERT ... VALUES.
 INSERT INTO t1 VALUES (1, 2, 3), (10, 20, 30), (100, 200, 300);
 ERROR 23000: Column 'a' cannot be null
@@ -110,6 +186,21 @@ a	b	c
 
 DELETE FROM t1;
 
+# Multi REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (1, 2, 3), (10, 20, 30), (100, 200, 300);
+ERROR 23000: Column 'a' cannot be null
+REPLACE INTO t1(a, b, c) VALUES (1, 2, 3), (10, 20, 30), (100, 200, 300);
+ERROR 23000: Column 'a' cannot be null
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+ERROR 23000: Column 'a' cannot be null
+REPLACE INTO t1(a) VALUES (1), (10), (100);
+ERROR 23000: Column 'a' cannot be null
+
+SELECT * FROM t1;
+a	b	c
+
+DELETE FROM t1;
+
 # INSERT ... SELECT.
 INSERT INTO t1 SELECT * FROM t2;
 ERROR 23000: Column 'a' cannot be null
@@ -119,6 +210,26 @@ INSERT INTO t1(b, c) SELECT b, c FROM t2
 ERROR 23000: Column 'a' cannot be null
 INSERT INTO t1(a) SELECT a FROM t2;
 ERROR 23000: Column 'a' cannot be null
+
+SELECT * FROM t1;
+a	b	c
+
+DELETE FROM t1;
+
+# REPLACE ... SELECT.
+REPLACE INTO t1 SELECT * FROM t2;
+ERROR 23000: Column 'a' cannot be null
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+ERROR 23000: Column 'a' cannot be null
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+ERROR 23000: Column 'a' cannot be null
+REPLACE INTO t1(a) SELECT a FROM t2;
+ERROR 23000: Column 'a' cannot be null
+
+SELECT * FROM t1;
+a	b	c
+
+DELETE FROM t1;
 DROP TRIGGER t1_bi;
 
 ###################################################################
@@ -239,6 +350,21 @@ a	b	c
 
 DELETE FROM t1;
 
+# Single REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (NULL, 2, 3);
+REPLACE INTO t1(a, b, c) VALUES (NULL, 20, 30);
+REPLACE INTO t1(b, c) VALUES (200, 300);
+REPLACE INTO t1(a) VALUES (NULL);
+
+SELECT * FROM t1;
+a	b	c
+1	NULL	3
+1	NULL	30
+1	NULL	300
+1	NULL	NULL
+
+DELETE FROM t1;
+
 # Multi INSERT ... VALUES.
 INSERT INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
 INSERT INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
@@ -262,6 +388,29 @@ a	b	c
 
 DELETE FROM t1;
 
+# Multi REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+REPLACE INTO t1(a) VALUES (-3), (NULL), (NULL);
+
+SELECT * FROM t1;
+a	b	c
+1	-1	3
+1	NULL	30
+1	NULL	300
+1	-2	3
+1	NULL	30
+1	NULL	300
+1	NULL	3
+1	NULL	30
+1	NULL	300
+1	-3	NULL
+1	NULL	NULL
+1	NULL	NULL
+
+DELETE FROM t1;
+
 # INSERT ... SELECT
 INSERT INTO t1 SELECT * FROM t2;
 INSERT INTO t1(a, b, c) SELECT * FROM t2;
@@ -284,6 +433,29 @@ a	b	c
 1	NULL	NULL
 
 DELETE FROM t1;
+
+# REPLACE ... SELECT
+REPLACE INTO t1 SELECT * FROM t2;
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+REPLACE INTO t1(a) SELECT a FROM t2;
+
+SELECT * FROM t1;
+a	b	c
+1	1	3
+1	NULL	30
+1	NULL	300
+1	1	3
+1	NULL	30
+1	NULL	300
+1	NULL	3
+1	NULL	30
+1	NULL	300
+1	1	NULL
+1	NULL	NULL
+1	NULL	NULL
+
+DELETE FROM t1;
 DROP TRIGGER t1_bi;
 
 ###################################################################
@@ -310,6 +482,21 @@ a	b	c
 
 DELETE FROM t1;
 
+# Single REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (NULL, 2, 3);
+REPLACE INTO t1(a, b, c) VALUES (NULL, 20, 30);
+REPLACE INTO t1(b, c) VALUES (200, 300);
+REPLACE INTO t1(a) VALUES (NULL);
+
+SELECT * FROM t1;
+a	b	c
+99	99	3
+99	99	30
+99	99	300
+99	99	NULL
+
+DELETE FROM t1;
+
 # Multi INSERT ... VALUES.
 INSERT INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
 INSERT INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
@@ -333,6 +520,29 @@ a	b	c
 
 DELETE FROM t1;
 
+# Multi REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+REPLACE INTO t1(a) VALUES (-3), (NULL), (NULL);
+
+SELECT * FROM t1;
+a	b	c
+99	99	3
+99	99	30
+99	99	300
+99	99	3
+99	99	30
+99	99	300
+99	99	3
+99	99	30
+99	99	300
+99	99	NULL
+99	99	NULL
+99	99	NULL
+
+DELETE FROM t1;
+
 # INSERT ... SELECT
 INSERT INTO t1 SELECT * FROM t2;
 INSERT INTO t1(a, b, c) SELECT * FROM t2;
@@ -355,6 +565,29 @@ a	b	c
 99	99	NULL
 
 DELETE FROM t1;
+
+# REPLACE ... SELECT
+REPLACE INTO t1 SELECT * FROM t2;
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+REPLACE INTO t1(a) SELECT a FROM t2;
+
+SELECT * FROM t1;
+a	b	c
+99	99	3
+99	99	30
+99	99	300
+99	99	3
+99	99	30
+99	99	300
+99	99	3
+99	99	30
+99	99	300
+99	99	NULL
+99	99	NULL
+99	99	NULL
+
+DELETE FROM t1;
 DELETE FROM t2;
 DROP TRIGGER t1_bi;
 
@@ -426,6 +659,21 @@ a	b	c	a_new_is_null
 
 DELETE FROM t1;
 
+# Single REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (NULL, 2, 3, NULL);
+REPLACE INTO t1(a, b, c) VALUES (NULL, 20, 30);
+REPLACE INTO t1(b, c) VALUES (200, 300);
+REPLACE INTO t1(a) VALUES (NULL);
+
+SELECT * FROM t1;
+a	b	c	a_new_is_null
+99	2	3	1
+99	20	30	1
+99	200	300	1
+99	NULL	NULL	1
+
+DELETE FROM t1;
+
 # Multi INSERT ... VALUES.
 INSERT INTO t1 VALUES
 (-1, 2, 3, NULL), (NULL, 20, 30, NULL), (NULL, 200, 300, NULL);
@@ -450,6 +698,30 @@ a	b	c	a_new_is_null
 
 DELETE FROM t1;
 
+# Multi REPLACE ... VALUES.
+REPLACE INTO t1 VALUES
+(-1, 2, 3, NULL), (NULL, 20, 30, NULL), (NULL, 200, 300, NULL);
+REPLACE INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+REPLACE INTO t1(a) VALUES (-3), (NULL), (NULL);
+
+SELECT * FROM t1;
+a	b	c	a_new_is_null
+99	2	3	0
+99	20	30	1
+99	200	300	1
+99	2	3	0
+99	20	30	1
+99	200	300	1
+99	2	3	1
+99	20	30	1
+99	200	300	1
+99	NULL	NULL	0
+99	NULL	NULL	1
+99	NULL	NULL	1
+
+DELETE FROM t1;
+
 # INSERT ... SELECT
 INSERT INTO t1 SELECT t2.*, NULL FROM t2;
 INSERT INTO t1(a, b, c) SELECT * FROM t2;
@@ -472,6 +744,29 @@ a	b	c	a_new_is_null
 99	NULL	NULL	1
 
 DELETE FROM t1;
+
+# REPLACE ... SELECT
+REPLACE INTO t1 SELECT t2.*, NULL FROM t2;
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+REPLACE INTO t1(a) SELECT a FROM t2;
+
+SELECT * FROM t1;
+a	b	c	a_new_is_null
+99	2	3	0
+99	20	30	1
+99	200	300	1
+99	2	3	0
+99	20	30	1
+99	200	300	1
+99	2	3	1
+99	20	30	1
+99	200	300	1
+99	NULL	NULL	0
+99	NULL	NULL	1
+99	NULL	NULL	1
+
+DELETE FROM t1;
 DROP TRIGGER t1_bi;
 
 ###################################################################
@@ -528,13 +823,25 @@ DROP TABLE t2;
 # Test 6: Nullability of non-updated columns.
 ###################################################################
 CREATE TABLE t1(a INT, b INT NOT NULL);
-CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET NEW.b = NULL;
-INSERT INTO t1(a) VALUES(1);
+
+# - Unconditional SET in a trigger.
+
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+SET NEW.b = NULL;
+
+INSERT INTO t1(a) VALUES (1);
+ERROR 23000: Column 'b' cannot be null
+
+REPLACE INTO t1(a) VALUES (1);
 ERROR 23000: Column 'b' cannot be null
+
 SELECT * FROM t1;
 a	b
-DROP TRIGGER t1_bi;
 DELETE FROM t1;
+DROP TRIGGER t1_bi;
+
+# - Conditional SET in a trigger, which is executed for every row.
+
 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
 BEGIN
 SET NEW.b = NEW.a;
@@ -542,22 +849,37 @@ IF NEW.b IS NULL THEN
 SET NEW.b = 1;
 END IF;
 END|
-INSERT INTO t1(a) VALUES(NULL);
+
+INSERT INTO t1(a) VALUES (NULL);
+
+REPLACE INTO t1(a) VALUES (NULL);
+
 SELECT * FROM t1;
 a	b
 NULL	1
-DROP TRIGGER t1_bi;
+NULL	1
 DELETE FROM t1;
+DROP TRIGGER t1_bi;
+
+# - Conditional SET in a trigger, which is NOT executed for every row.
+
 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
 BEGIN
 IF (MOD(NEW.a, 2) = 0) THEN
 SET NEW.b = NEW.a - 1;
 END IF;
 END|
+
 INSERT INTO t1(a) VALUES (1), (2), (3), (4), (5), (6);
 Warnings:
 Warning	1048	Column 'b' cannot be null
 Warning	1364	Field 'b' doesn't have a default value
+
+REPLACE INTO t1(a) VALUES (1), (2), (3), (4), (5), (6);
+Warnings:
+Warning	1048	Column 'b' cannot be null
+Warning	1364	Field 'b' doesn't have a default value
+
 SELECT * FROM t1;
 a	b
 1	0
@@ -566,30 +888,46 @@ a	b
 4	3
 5	0
 6	5
+1	0
+2	1
+3	0
+4	3
+5	0
+6	5
 DROP TABLE t1;
 
 ###################################################################
 # Test 7: Nullability of column being copied as result of INSERT SELECT.
 ###################################################################
-CREATE TABLE t1 (a INT NOT NULL);
-CREATE TABLE t2 (a INT);
+CREATE TABLE t1(a INT NOT NULL);
+CREATE TABLE t2(a INT);
 INSERT INTO t2 VALUES (NULL);
-CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a = 1;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+SET NEW.a = 1;
+
 INSERT INTO t1 SELECT * FROM t2;
+REPLACE INTO t1 SELECT * FROM t2;
+
 SELECT * FROM t1;
 a
 1
+1
+
 DROP TRIGGER t1_bi;
 DROP TABLE t1,t2;
-CREATE TABLE t1 (a INT NOT NULL);
+CREATE TABLE t1(a INT NOT NULL);
 INSERT INTO t1 VALUES (1);
-CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET NEW.a = 2;
-CREATE TABLE t2 (a INT);
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+SET NEW.a = 2;
+CREATE TABLE t2(a INT);
 INSERT INTO t2 VALUES (NULL);
+
 UPDATE t1, t2 SET t1.a = t2.a;
+
 SELECT * FROM t1;
 a
 2
+
 DROP TRIGGER t1_bu;
 DROP TABLE t1,t2;
 
@@ -661,6 +999,14 @@ ERROR 23000: Column 'b' cannot be null
 SELECT * FROM t1;
 a	b
 
+REPLACE INTO t1 VALUES (1, NULL);
+ERROR 23000: Column 'b' cannot be null
+REPLACE INTO v1 VALUES (1, NULL);
+ERROR 23000: Column 'b' cannot be null
+
+SELECT * FROM t1;
+a	b
+
 INSERT INTO t2 VALUES (1, 2, NULL, 4);
 ERROR 23000: Column 'c' cannot be null
 INSERT INTO v2 VALUES (1, 2, NULL, 4);
@@ -669,6 +1015,14 @@ ERROR 23000: Column 'c' cannot be null
 SELECT * FROM t2;
 a	b	c	d
 
+REPLACE INTO t2 VALUES (1, 2, NULL, 4);
+ERROR 23000: Column 'c' cannot be null
+REPLACE INTO v2 VALUES (1, 2, NULL, 4);
+ERROR 23000: Column 'c' cannot be null
+
+SELECT * FROM t2;
+a	b	c	d
+
 #   - All columns + NULL-value for NOT NULL column.
 
 INSERT INTO v1(a, b) VALUES (1, NULL);
@@ -679,6 +1033,14 @@ ERROR 23000: Column 'b' cannot be null
 SELECT * FROM t1;
 a	b
 
+REPLACE INTO v1(a, b) VALUES (1, NULL);
+ERROR 23000: Column 'b' cannot be null
+REPLACE INTO t1(a, b) VALUES (1, NULL);
+ERROR 23000: Column 'b' cannot be null
+
+SELECT * FROM t1;
+a	b
+
 INSERT INTO t2(a, b, c, d) VALUES (1, 2, NULL, 4);
 ERROR 23000: Column 'c' cannot be null
 INSERT INTO v2(a, b, c, d) VALUES (1, 2, NULL, 4);
@@ -687,6 +1049,14 @@ ERROR 23000: Column 'c' cannot be null
 SELECT * FROM t2;
 a	b	c	d
 
+REPLACE INTO t2(a, b, c, d) VALUES (1, 2, NULL, 4);
+ERROR 23000: Column 'c' cannot be null
+REPLACE INTO v2(a, b, c, d) VALUES (1, 2, NULL, 4);
+ERROR 23000: Column 'c' cannot be null
+
+SELECT * FROM t2;
+a	b	c	d
+
 #   - Single nullable column, no values for NOT NULL columns.
 #     Expect exactly 4 warnings and 8 rows being inserted into t1.
 
@@ -713,6 +1083,32 @@ a	b
 6	0
 7	0
 8	0
+DELETE FROM t1;
+
+REPLACE INTO t1(a) VALUES (1);
+Warnings:
+Warning	1364	Field 'b' doesn't have a default value
+REPLACE INTO t1(a) VALUES (2), (3), (4);
+Warnings:
+Warning	1364	Field 'b' doesn't have a default value
+REPLACE INTO v1(a) VALUES (5);
+Warnings:
+Warning	1423	Field of view 'test.v1' underlying table doesn't have a default value
+REPLACE INTO v1(a) VALUES (6), (7), (8);
+Warnings:
+Warning	1423	Field of view 'test.v1' underlying table doesn't have a default value
+
+SELECT * FROM t1;
+a	b
+1	0
+2	0
+3	0
+4	0
+5	0
+6	0
+7	0
+8	0
+DELETE FROM t1;
 
 INSERT INTO t2(a) VALUES (1);
 Warnings:
@@ -745,8 +1141,39 @@ a	b	c	d
 6	0	0	0
 7	0	0	0
 8	0	0	0
+DELETE FROM t2;
 
-DELETE FROM t1;
+REPLACE INTO t2(a) VALUES (1);
+Warnings:
+Warning	1364	Field 'b' doesn't have a default value
+Warning	1364	Field 'c' doesn't have a default value
+Warning	1364	Field 'd' doesn't have a default value
+REPLACE INTO t2(a) VALUES (2), (3), (4);
+Warnings:
+Warning	1364	Field 'b' doesn't have a default value
+Warning	1364	Field 'c' doesn't have a default value
+Warning	1364	Field 'd' doesn't have a default value
+REPLACE INTO v2(a) VALUES (5);
+Warnings:
+Warning	1423	Field of view 'test.v2' underlying table doesn't have a default value
+Warning	1423	Field of view 'test.v2' underlying table doesn't have a default value
+Warning	1423	Field of view 'test.v2' underlying table doesn't have a default value
+REPLACE INTO v2(a) VALUES (6), (7), (8);
+Warnings:
+Warning	1423	Field of view 'test.v2' underlying table doesn't have a default value
+Warning	1423	Field of view 'test.v2' underlying table doesn't have a default value
+Warning	1423	Field of view 'test.v2' underlying table doesn't have a default value
+
+SELECT * FROM t2;
+a	b	c	d
+1	0	0	0
+2	0	0	0
+3	0	0	0
+4	0	0	0
+5	0	0	0
+6	0	0	0
+7	0	0	0
+8	0	0	0
 DELETE FROM t2;
 
 #------------------------------------------------------------------
@@ -773,9 +1200,30 @@ NULL	0
 NULL	220
 310	0
 NULL	0
+DELETE FROM t1;
+
+REPLACE INTO t1 SELECT * FROM t1_data;
+Warnings:
+Warning	1048	Column 'b' cannot be null
+REPLACE INTO v1 SELECT a * 10, b * 10 FROM t1_data;
+Warnings:
+Warning	1048	Column 'b' cannot be null
+
+SELECT * FROM t1;
+a	b
+11	12
+NULL	22
+31	0
+NULL	0
+110	120
+NULL	220
+310	0
+NULL	0
+DELETE FROM t1;
 
 #   - No column list (all columns) + NULL-value for NOT NULL column.
 #     Expect 4 warnings for each statement.
+
 INSERT INTO t2 SELECT * FROM t2_data;
 Warnings:
 Warning	1048	Column 'b' cannot be null
@@ -801,6 +1249,34 @@ NULL	220	230	240
 410	420	0	440
 510	520	530	0
 NULL	0	0	0
+DELETE FROM t2;
+
+REPLACE INTO t2 SELECT * FROM t2_data;
+Warnings:
+Warning	1048	Column 'b' cannot be null
+Warning	1048	Column 'c' cannot be null
+Warning	1048	Column 'd' cannot be null
+REPLACE INTO v2 SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
+Warnings:
+Warning	1048	Column 'b' cannot be null
+Warning	1048	Column 'c' cannot be null
+Warning	1048	Column 'd' cannot be null
+
+SELECT * FROM t2;
+a	b	c	d
+11	12	13	14
+NULL	22	23	24
+31	0	33	34
+41	42	0	44
+51	52	53	0
+NULL	0	0	0
+110	120	130	140
+NULL	220	230	240
+310	0	330	340
+410	420	0	440
+510	520	530	0
+NULL	0	0	0
+DELETE FROM t2;
 
 #   - All columns + NULL-value for NOT NULL column.
 #     Expect 4 warnings for each statement.
@@ -822,6 +1298,17 @@ NULL	0
 NULL	220
 310	0
 NULL	0
+DELETE FROM t1;
+
+REPLACE INTO t1(a, b) SELECT * FROM t1_data;
+Warnings:
+Warning	1048	Column 'b' cannot be null
+REPLACE INTO v1(a, b) SELECT a * 10, b * 10 FROM t1_data;
+Warnings:
+Warning	1048	Column 'b' cannot be null
+
+SELECT * FROM t1;
+a	b
 11	12
 NULL	22
 31	0
@@ -830,6 +1317,7 @@ NULL	0
 NULL	220
 310	0
 NULL	0
+DELETE FROM t1;
 
 INSERT INTO t2(a, b, c, d) SELECT * FROM t2_data;
 Warnings:
@@ -856,6 +1344,21 @@ NULL	220	230	240
 410	420	0	440
 510	520	530	0
 NULL	0	0	0
+DELETE FROM t2;
+
+REPLACE INTO t2(a, b, c, d) SELECT * FROM t2_data;
+Warnings:
+Warning	1048	Column 'b' cannot be null
+Warning	1048	Column 'c' cannot be null
+Warning	1048	Column 'd' cannot be null
+REPLACE INTO v2(a, b, c, d) SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
+Warnings:
+Warning	1048	Column 'b' cannot be null
+Warning	1048	Column 'c' cannot be null
+Warning	1048	Column 'd' cannot be null
+
+SELECT * FROM t2;
+a	b	c	d
 11	12	13	14
 NULL	22	23	24
 31	0	33	34
@@ -868,6 +1371,7 @@ NULL	220	230	240
 410	420	0	440
 510	520	530	0
 NULL	0	0	0
+DELETE FROM t2;
 
 #   - Single nullable column, no values for NOT NULL columns.
 #     Expect 4 warnings for each statement.
@@ -881,22 +1385,25 @@ Warning	1423	Field of view 'test.v1' und
 
 SELECT * FROM t1;
 a	b
-11	12
-NULL	22
-31	0
-NULL	0
-110	120
-NULL	220
-310	0
+11	0
 NULL	0
-11	12
-NULL	22
 31	0
 NULL	0
-110	120
-NULL	220
-310	0
+1100	0
+NULL	0
+3100	0
 NULL	0
+DELETE FROM t1;
+
+REPLACE INTO t1(a) SELECT a FROM t1_data;
+Warnings:
+Warning	1364	Field 'b' doesn't have a default value
+REPLACE INTO v1(a) SELECT a * 100 FROM t1_data;
+Warnings:
+Warning	1423	Field of view 'test.v1' underlying table doesn't have a default value
+
+SELECT * FROM t1;
+a	b
 11	0
 NULL	0
 31	0
@@ -905,6 +1412,7 @@ NULL	0
 NULL	0
 3100	0
 NULL	0
+DELETE FROM t1;
 
 INSERT INTO t2(a) SELECT a FROM t2_data;
 Warnings:
@@ -919,30 +1427,33 @@ Warning	1423	Field of view 'test.v2' und
 
 SELECT * FROM t2;
 a	b	c	d
-11	12	13	14
-NULL	22	23	24
-31	0	33	34
-41	42	0	44
-51	52	53	0
+11	0	0	0
 NULL	0	0	0
-110	120	130	140
-NULL	220	230	240
-310	0	330	340
-410	420	0	440
-510	520	530	0
+31	0	0	0
+41	0	0	0
+51	0	0	0
 NULL	0	0	0
-11	12	13	14
-NULL	22	23	24
-31	0	33	34
-41	42	0	44
-51	52	53	0
+1100	0	0	0
 NULL	0	0	0
-110	120	130	140
-NULL	220	230	240
-310	0	330	340
-410	420	0	440
-510	520	530	0
+3100	0	0	0
+4100	0	0	0
+5100	0	0	0
 NULL	0	0	0
+DELETE FROM t2;
+
+REPLACE INTO t2(a) SELECT a FROM t2_data;
+Warnings:
+Warning	1364	Field 'b' doesn't have a default value
+Warning	1364	Field 'c' doesn't have a default value
+Warning	1364	Field 'd' doesn't have a default value
+REPLACE INTO v2(a) SELECT a * 100 FROM t2_data;
+Warnings:
+Warning	1423	Field of view 'test.v2' underlying table doesn't have a default value
+Warning	1423	Field of view 'test.v2' underlying table doesn't have a default value
+Warning	1423	Field of view 'test.v2' underlying table doesn't have a default value
+
+SELECT * FROM t2;
+a	b	c	d
 11	0	0	0
 NULL	0	0	0
 31	0	0	0
@@ -955,8 +1466,6 @@ NULL	0	0	0
 4100	0	0	0
 5100	0	0	0
 NULL	0	0	0
-
-DELETE FROM t1;
 DELETE FROM t2;
 
 #------------------------------------------------------------------
@@ -1036,6 +1545,14 @@ ERROR 23000: Column 'b' cannot be null
 SELECT * FROM t1;
 a	b
 
+REPLACE INTO t1 VALUES (1, NULL);
+ERROR 23000: Column 'b' cannot be null
+REPLACE INTO v1 VALUES (1, NULL);
+ERROR 23000: Column 'b' cannot be null
+
+SELECT * FROM t1;
+a	b
+
 INSERT INTO t2 VALUES (1, 2, NULL, 4);
 ERROR 23000: Column 'c' cannot be null
 INSERT INTO v2 VALUES (1, 2, NULL, 4);
@@ -1044,6 +1561,14 @@ ERROR 23000: Column 'c' cannot be null
 SELECT * FROM t2;
 a	b	c	d
 
+REPLACE INTO t2 VALUES (1, 2, NULL, 4);
+ERROR 23000: Column 'c' cannot be null
+REPLACE INTO v2 VALUES (1, 2, NULL, 4);
+ERROR 23000: Column 'c' cannot be null
+
+SELECT * FROM t2;
+a	b	c	d
+
 #   - All columns + NULL-value for NOT NULL column.
 
 INSERT INTO v1(a, b) VALUES (1, NULL);
@@ -1054,6 +1579,14 @@ ERROR 23000: Column 'b' cannot be null
 SELECT * FROM t1;
 a	b
 
+REPLACE INTO v1(a, b) VALUES (1, NULL);
+ERROR 23000: Column 'b' cannot be null
+REPLACE INTO t1(a, b) VALUES (1, NULL);
+ERROR 23000: Column 'b' cannot be null
+
+SELECT * FROM t1;
+a	b
+
 INSERT INTO t2(a, b, c, d) VALUES (1, 2, NULL, 4);
 ERROR 23000: Column 'c' cannot be null
 INSERT INTO v2(a, b, c, d) VALUES (1, 2, NULL, 4);
@@ -1062,6 +1595,14 @@ ERROR 23000: Column 'c' cannot be null
 SELECT * FROM t2;
 a	b	c	d
 
+REPLACE INTO t2(a, b, c, d) VALUES (1, 2, NULL, 4);
+ERROR 23000: Column 'c' cannot be null
+REPLACE INTO v2(a, b, c, d) VALUES (1, 2, NULL, 4);
+ERROR 23000: Column 'c' cannot be null
+
+SELECT * FROM t2;
+a	b	c	d
+
 #   - Single nullable column, no values for NOT NULL columns.
 
 INSERT INTO t1(a) VALUES (1);
@@ -1075,6 +1616,20 @@ ERROR HY000: Field of view 'test.v1' und
 
 SELECT * FROM t1;
 a	b
+DELETE FROM t1;
+
+REPLACE INTO t1(a) VALUES (1);
+ERROR HY000: Field 'b' doesn't have a default value
+REPLACE INTO t1(a) VALUES (2), (3), (4);
+ERROR HY000: Field 'b' doesn't have a default value
+REPLACE INTO v1(a) VALUES (5);
+ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default value
+REPLACE INTO v1(a) VALUES (6), (7), (8);
+ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default value
+
+SELECT * FROM t1;
+a	b
+DELETE FROM t1;
 
 INSERT INTO t2(a) VALUES (1);
 ERROR HY000: Field 'b' doesn't have a default value
@@ -1087,8 +1642,19 @@ ERROR HY000: Field of view 'test.v2' und
 
 SELECT * FROM t2;
 a	b	c	d
+DELETE FROM t2;
 
-DELETE FROM t1;
+REPLACE INTO t2(a) VALUES (1);
+ERROR HY000: Field 'b' doesn't have a default value
+REPLACE INTO t2(a) VALUES (2), (3), (4);
+ERROR HY000: Field 'b' doesn't have a default value
+REPLACE INTO v2(a) VALUES (5);
+ERROR HY000: Field of view 'test.v2' underlying table doesn't have a default value
+REPLACE INTO v2(a) VALUES (6), (7), (8);
+ERROR HY000: Field of view 'test.v2' underlying table doesn't have a default value
+
+SELECT * FROM t2;
+a	b	c	d
 DELETE FROM t2;
 
 #------------------------------------------------------------------
@@ -1110,9 +1676,22 @@ a	b
 NULL	22
 110	120
 NULL	220
+DELETE FROM t1;
+
+REPLACE INTO t1 SELECT * FROM t1_data;
+ERROR 23000: Column 'b' cannot be null
+REPLACE INTO v1 SELECT a * 10, b * 10 FROM t1_data;
+ERROR 23000: Column 'b' cannot be null
 
+# The following SELECT output should have 4 rows.
+# t1's engine is MyISAM, so the transaction can not be fully rolled back.
+SELECT * FROM t1;
+a	b
+11	12
+NULL	22
+110	120
+NULL	220
 DELETE FROM t1;
-DELETE FROM t2;
 
 #   - No column list (all columns) + NULL-value for NOT NULL column.
 INSERT INTO t2 SELECT * FROM t2_data;
@@ -1128,8 +1707,22 @@ a	b	c	d
 NULL	22	23	24
 110	120	130	140
 NULL	220	230	240
+DELETE FROM t2;
 
-DELETE FROM t1;
+#   - No column list (all columns) + NULL-value for NOT NULL column.
+REPLACE INTO t2 SELECT * FROM t2_data;
+ERROR 23000: Column 'b' cannot be null
+REPLACE INTO v2 SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
+ERROR 23000: Column 'b' cannot be null
+
+# The following SELECT output should have 4 rows.
+# t2's engine is MyISAM, so the transaction can not be fully rolled back.
+SELECT * FROM t2;
+a	b	c	d
+11	12	13	14
+NULL	22	23	24
+110	120	130	140
+NULL	220	230	240
 DELETE FROM t2;
 
 #   - All columns + NULL-value for NOT NULL column.
@@ -1147,9 +1740,22 @@ a	b
 NULL	22
 110	120
 NULL	220
+DELETE FROM t1;
 
+REPLACE INTO t1(a, b) SELECT * FROM t1_data;
+ERROR 23000: Column 'b' cannot be null
+REPLACE INTO v1(a, b) SELECT a * 10, b * 10 FROM t1_data;
+ERROR 23000: Column 'b' cannot be null
+
+# The following SELECT output should have 4 rows.
+# t1's engine is MyISAM, so the transaction can not be fully rolled back.
+SELECT * FROM t1;
+a	b
+11	12
+NULL	22
+110	120
+NULL	220
 DELETE FROM t1;
-DELETE FROM t2;
 
 INSERT INTO t2(a, b, c, d) SELECT * FROM t2_data;
 ERROR 23000: Column 'b' cannot be null
@@ -1164,8 +1770,21 @@ a	b	c	d
 NULL	22	23	24
 110	120	130	140
 NULL	220	230	240
+DELETE FROM t2;
 
-DELETE FROM t1;
+REPLACE INTO t2(a, b, c, d) SELECT * FROM t2_data;
+ERROR 23000: Column 'b' cannot be null
+REPLACE INTO v2(a, b, c, d) SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
+ERROR 23000: Column 'b' cannot be null
+
+# The following SELECT output should have 4 rows.
+# t2's engine is MyISAM, so the transaction can not be fully rolled back.
+SELECT * FROM t2;
+a	b	c	d
+11	12	13	14
+NULL	22	23	24
+110	120	130	140
+NULL	220	230	240
 DELETE FROM t2;
 
 #   - Single nullable column, no values for NOT NULL columns.
@@ -1178,9 +1797,17 @@ ERROR HY000: Field of view 'test.v1' und
 # The following SELECT output should have 0 rows.
 SELECT * FROM t1;
 a	b
+DELETE FROM t1;
 
+REPLACE INTO t1(a) SELECT a FROM t1_data;
+ERROR HY000: Field 'b' doesn't have a default value
+REPLACE INTO v1(a) SELECT a * 100 FROM t1_data;
+ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default value
+
+# The following SELECT output should have 0 rows.
+SELECT * FROM t1;
+a	b
 DELETE FROM t1;
-DELETE FROM t2;
 
 INSERT INTO t2(a) SELECT a FROM t2_data;
 ERROR HY000: Field 'b' doesn't have a default value
@@ -1190,8 +1817,16 @@ ERROR HY000: Field of view 'test.v2' und
 # The following SELECT output should have 0 rows.
 SELECT * FROM t2;
 a	b	c	d
+DELETE FROM t2;
 
-DELETE FROM t1;
+REPLACE INTO t2(a) SELECT a FROM t2_data;
+ERROR HY000: Field 'b' doesn't have a default value
+REPLACE INTO v2(a) SELECT a * 100 FROM t2_data;
+ERROR HY000: Field of view 'test.v2' underlying table doesn't have a default value
+
+# The following SELECT output should have 0 rows.
+SELECT * FROM t2;
+a	b	c	d
 DELETE FROM t2;
 
 #------------------------------------------------------------------

=== modified file 'mysql-test/t/wl6030.test'
--- a/mysql-test/t/wl6030.test	2012-09-28 07:55:02 +0000
+++ b/mysql-test/t/wl6030.test	2012-10-04 15:09:30 +0000
@@ -28,6 +28,18 @@ SELECT * FROM t1;
 DELETE FROM t1;
 
 --echo
+--echo # Single REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (NULL, 2, 3);
+REPLACE INTO t1(a, b, c) VALUES (NULL, 20, 30);
+REPLACE INTO t1(b, c) VALUES (200, 300);
+REPLACE INTO t1(a) VALUES (NULL);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
 --echo # Multi INSERT ... VALUES.
 INSERT INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
 INSERT INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
@@ -40,6 +52,18 @@ SELECT * FROM t1;
 DELETE FROM t1;
 
 --echo
+--echo # Multi REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+REPLACE INTO t1(a) VALUES (-3), (NULL), (NULL);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
 --echo # INSERT ... SELECT.
 INSERT INTO t1 SELECT * FROM t2;
 INSERT INTO t1(a, b, c) SELECT * FROM t2;
@@ -50,6 +74,18 @@ INSERT INTO t1(a) SELECT a FROM t2;
 SELECT * FROM t1;
 --echo
 DELETE FROM t1;
+
+--echo
+--echo # REPLACE ... SELECT.
+REPLACE INTO t1 SELECT * FROM t2;
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+REPLACE INTO t1(a) SELECT a FROM t2;
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
 DELETE FROM t2;
 
 DROP TRIGGER t1_bi;
@@ -82,6 +118,22 @@ SELECT * FROM t1;
 DELETE FROM t1;
 
 --echo
+--echo # Single REPLACE ... VALUES.
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1 VALUES (1, 2, 3);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a, b, c) VALUES (1, 2, 3);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(b, c) VALUES (2, 3);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a) VALUES (1);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
 --echo # Multi INSERT ... VALUES.
 --error ER_BAD_NULL_ERROR
 INSERT INTO t1 VALUES (1, 2, 3), (10, 20, 30), (100, 200, 300);
@@ -98,6 +150,22 @@ SELECT * FROM t1;
 DELETE FROM t1;
 
 --echo
+--echo # Multi REPLACE ... VALUES.
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1 VALUES (1, 2, 3), (10, 20, 30), (100, 200, 300);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a, b, c) VALUES (1, 2, 3), (10, 20, 30), (100, 200, 300);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a) VALUES (1), (10), (100);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
 --echo # INSERT ... SELECT.
 --error ER_BAD_NULL_ERROR
 INSERT INTO t1 SELECT * FROM t2;
@@ -108,6 +176,27 @@ INSERT INTO t1(b, c) SELECT b, c FROM t2
 --error ER_BAD_NULL_ERROR
 INSERT INTO t1(a) SELECT a FROM t2;
 
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
+--echo # REPLACE ... SELECT.
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1 SELECT * FROM t2;
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a) SELECT a FROM t2;
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
 DROP TRIGGER t1_bi;
 
 --echo
@@ -226,6 +315,18 @@ SELECT * FROM t1;
 DELETE FROM t1;
 
 --echo
+--echo # Single REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (NULL, 2, 3);
+REPLACE INTO t1(a, b, c) VALUES (NULL, 20, 30);
+REPLACE INTO t1(b, c) VALUES (200, 300);
+REPLACE INTO t1(a) VALUES (NULL);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
 --echo # Multi INSERT ... VALUES.
 INSERT INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
 INSERT INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
@@ -238,6 +339,18 @@ SELECT * FROM t1;
 DELETE FROM t1;
 
 --echo
+--echo # Multi REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+REPLACE INTO t1(a) VALUES (-3), (NULL), (NULL);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
 --echo # INSERT ... SELECT
 INSERT INTO t1 SELECT * FROM t2;
 INSERT INTO t1(a, b, c) SELECT * FROM t2;
@@ -249,6 +362,18 @@ SELECT * FROM t1;
 --echo
 DELETE FROM t1;
 
+--echo
+--echo # REPLACE ... SELECT
+REPLACE INTO t1 SELECT * FROM t2;
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+REPLACE INTO t1(a) SELECT a FROM t2;
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
 DROP TRIGGER t1_bi;
 
 --echo
@@ -275,6 +400,19 @@ INSERT INTO t1(a) VALUES (NULL);
 SELECT * FROM t1;
 --echo
 DELETE FROM t1;
+
+--echo
+--echo # Single REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (NULL, 2, 3);
+REPLACE INTO t1(a, b, c) VALUES (NULL, 20, 30);
+REPLACE INTO t1(b, c) VALUES (200, 300);
+REPLACE INTO t1(a) VALUES (NULL);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
 --echo
 --echo # Multi INSERT ... VALUES.
 INSERT INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
@@ -288,6 +426,18 @@ SELECT * FROM t1;
 DELETE FROM t1;
 
 --echo
+--echo # Multi REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (-1, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+REPLACE INTO t1(a) VALUES (-3), (NULL), (NULL);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
 --echo # INSERT ... SELECT
 INSERT INTO t1 SELECT * FROM t2;
 INSERT INTO t1(a, b, c) SELECT * FROM t2;
@@ -298,6 +448,18 @@ INSERT INTO t1(a) SELECT a FROM t2;
 SELECT * FROM t1;
 --echo
 DELETE FROM t1;
+
+--echo
+--echo # REPLACE ... SELECT
+REPLACE INTO t1 SELECT * FROM t2;
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+REPLACE INTO t1(a) SELECT a FROM t2;
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
 DELETE FROM t2;
 
 DROP TRIGGER t1_bi;
@@ -372,6 +534,18 @@ SELECT * FROM t1;
 DELETE FROM t1;
 
 --echo
+--echo # Single REPLACE ... VALUES.
+REPLACE INTO t1 VALUES (NULL, 2, 3, NULL);
+REPLACE INTO t1(a, b, c) VALUES (NULL, 20, 30);
+REPLACE INTO t1(b, c) VALUES (200, 300);
+REPLACE INTO t1(a) VALUES (NULL);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
 --echo # Multi INSERT ... VALUES.
 INSERT INTO t1 VALUES
   (-1, 2, 3, NULL), (NULL, 20, 30, NULL), (NULL, 200, 300, NULL);
@@ -385,6 +559,19 @@ SELECT * FROM t1;
 DELETE FROM t1;
 
 --echo
+--echo # Multi REPLACE ... VALUES.
+REPLACE INTO t1 VALUES
+  (-1, 2, 3, NULL), (NULL, 20, 30, NULL), (NULL, 200, 300, NULL);
+REPLACE INTO t1(a, b, c) VALUES (-2, 2, 3), (NULL, 20, 30), (NULL, 200, 300);
+REPLACE INTO t1(b, c) VALUES (2, 3), (20, 30), (200, 300);
+REPLACE INTO t1(a) VALUES (-3), (NULL), (NULL);
+
+--echo
+SELECT * FROM t1;
+--echo
+DELETE FROM t1;
+
+--echo
 --echo # INSERT ... SELECT
 INSERT INTO t1 SELECT t2.*, NULL FROM t2;
 INSERT INTO t1(a, b, c) SELECT * FROM t2;
@@ -394,8 +581,20 @@ INSERT INTO t1(a) SELECT a FROM t2;
 --echo
 SELECT * FROM t1;
 --echo
+DELETE FROM t1;
+
+--echo
+--echo # REPLACE ... SELECT
+REPLACE INTO t1 SELECT t2.*, NULL FROM t2;
+REPLACE INTO t1(a, b, c) SELECT * FROM t2;
+REPLACE INTO t1(b, c) SELECT b, c FROM t2;
+REPLACE INTO t1(a) SELECT a FROM t2;
 
+--echo
+SELECT * FROM t1;
+--echo
 DELETE FROM t1;
+
 DROP TRIGGER t1_bi;
 
 --echo
@@ -461,13 +660,32 @@ DROP TABLE t2;
 --echo ###################################################################
 
 CREATE TABLE t1(a INT, b INT NOT NULL);
-CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET NEW.b = NULL;
+
+--echo
+--echo # - Unconditional SET in a trigger.
+--echo
+
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+  SET NEW.b = NULL;
+
+--echo
 --error ER_BAD_NULL_ERROR
-INSERT INTO t1(a) VALUES(1);
+INSERT INTO t1(a) VALUES (1);
+
+--echo
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a) VALUES (1);
+
+--echo
 SELECT * FROM t1;
-DROP TRIGGER t1_bi;
 DELETE FROM t1;
 
+DROP TRIGGER t1_bi;
+
+--echo
+--echo # - Conditional SET in a trigger, which is executed for every row.
+--echo
+
 delimiter |;
 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
 BEGIN
@@ -477,11 +695,23 @@ BEGIN
   END IF;
 END|
 delimiter ;|
-INSERT INTO t1(a) VALUES(NULL);
+
+--echo
+INSERT INTO t1(a) VALUES (NULL);
+
+--echo
+REPLACE INTO t1(a) VALUES (NULL);
+
+--echo
 SELECT * FROM t1;
-DROP TRIGGER t1_bi;
 DELETE FROM t1;
 
+DROP TRIGGER t1_bi;
+
+--echo
+--echo # - Conditional SET in a trigger, which is NOT executed for every row.
+--echo
+
 delimiter |;
 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
 BEGIN
@@ -491,8 +721,13 @@ BEGIN
 END|
 delimiter ;|
 
+--echo
 INSERT INTO t1(a) VALUES (1), (2), (3), (4), (5), (6);
 
+--echo
+REPLACE INTO t1(a) VALUES (1), (2), (3), (4), (5), (6);
+
+--echo
 SELECT * FROM t1;
 
 DROP TABLE t1;
@@ -502,22 +737,41 @@ DROP TABLE t1;
 --echo # Test 7: Nullability of column being copied as result of INSERT SELECT.
 --echo ###################################################################
 
-CREATE TABLE t1 (a INT NOT NULL);
-CREATE TABLE t2 (a INT);
+CREATE TABLE t1(a INT NOT NULL);
+
+CREATE TABLE t2(a INT);
 INSERT INTO t2 VALUES (NULL);
-CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET NEW.a = 1;
+
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+  SET NEW.a = 1;
+
+--echo
 INSERT INTO t1 SELECT * FROM t2;
+REPLACE INTO t1 SELECT * FROM t2;
+
+--echo
 SELECT * FROM t1;
+--echo
+
 DROP TRIGGER t1_bi;
 DROP TABLE t1,t2;
 
-CREATE TABLE t1 (a INT NOT NULL);
+CREATE TABLE t1(a INT NOT NULL);
 INSERT INTO t1 VALUES (1);
-CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET NEW.a = 2;
-CREATE TABLE t2 (a INT);
+
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+  SET NEW.a = 2;
+
+CREATE TABLE t2(a INT);
 INSERT INTO t2 VALUES (NULL);
+
+--echo
 UPDATE t1, t2 SET t1.a = t2.a;
+
+--echo
 SELECT * FROM t1;
+--echo
+
 DROP TRIGGER t1_bu;
 DROP TABLE t1,t2;
 
@@ -605,6 +859,16 @@ INSERT INTO v1 VALUES (1, NULL);
 --echo
 SELECT * FROM t1;
 
+
+--echo
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1 VALUES (1, NULL);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v1 VALUES (1, NULL);
+
+--echo
+SELECT * FROM t1;
+
 --echo
 --error ER_BAD_NULL_ERROR
 INSERT INTO t2 VALUES (1, 2, NULL, 4);
@@ -615,6 +879,15 @@ INSERT INTO v2 VALUES (1, 2, NULL, 4);
 SELECT * FROM t2;
 
 --echo
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t2 VALUES (1, 2, NULL, 4);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v2 VALUES (1, 2, NULL, 4);
+
+--echo
+SELECT * FROM t2;
+
+--echo
 --echo #   - All columns + NULL-value for NOT NULL column.
 
 --echo
@@ -628,6 +901,15 @@ SELECT * FROM t1;
 
 --echo
 --error ER_BAD_NULL_ERROR
+REPLACE INTO v1(a, b) VALUES (1, NULL);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a, b) VALUES (1, NULL);
+
+--echo
+SELECT * FROM t1;
+
+--echo
+--error ER_BAD_NULL_ERROR
 INSERT INTO t2(a, b, c, d) VALUES (1, 2, NULL, 4);
 --error ER_BAD_NULL_ERROR
 INSERT INTO v2(a, b, c, d) VALUES (1, 2, NULL, 4);
@@ -636,6 +918,15 @@ INSERT INTO v2(a, b, c, d) VALUES (1, 2,
 SELECT * FROM t2;
 
 --echo
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t2(a, b, c, d) VALUES (1, 2, NULL, 4);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v2(a, b, c, d) VALUES (1, 2, NULL, 4);
+
+--echo
+SELECT * FROM t2;
+
+--echo
 --echo #   - Single nullable column, no values for NOT NULL columns.
 --echo #     Expect exactly 4 warnings and 8 rows being inserted into t1.
 
@@ -647,6 +938,17 @@ INSERT INTO v1(a) VALUES (6), (7), (8);
 
 --echo
 SELECT * FROM t1;
+DELETE FROM t1;
+
+--echo
+REPLACE INTO t1(a) VALUES (1);
+REPLACE INTO t1(a) VALUES (2), (3), (4);
+REPLACE INTO v1(a) VALUES (5);
+REPLACE INTO v1(a) VALUES (6), (7), (8);
+
+--echo
+SELECT * FROM t1;
+DELETE FROM t1;
 
 --echo
 INSERT INTO t2(a) VALUES (1);
@@ -656,9 +958,16 @@ INSERT INTO v2(a) VALUES (6), (7), (8);
 
 --echo
 SELECT * FROM t2;
+DELETE FROM t2;
 
 --echo
-DELETE FROM t1;
+REPLACE INTO t2(a) VALUES (1);
+REPLACE INTO t2(a) VALUES (2), (3), (4);
+REPLACE INTO v2(a) VALUES (5);
+REPLACE INTO v2(a) VALUES (6), (7), (8);
+
+--echo
+SELECT * FROM t2;
 DELETE FROM t2;
 
 --echo
@@ -676,15 +985,35 @@ INSERT INTO v1 SELECT a * 10, b * 10 FRO
 
 --echo
 SELECT * FROM t1;
+DELETE FROM t1;
+
+--echo
+REPLACE INTO t1 SELECT * FROM t1_data;
+REPLACE INTO v1 SELECT a * 10, b * 10 FROM t1_data;
+
+--echo
+SELECT * FROM t1;
+DELETE FROM t1;
 
 --echo
 --echo #   - No column list (all columns) + NULL-value for NOT NULL column.
 --echo #     Expect 4 warnings for each statement.
+
+--echo
 INSERT INTO t2 SELECT * FROM t2_data;
 INSERT INTO v2 SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
 
 --echo
 SELECT * FROM t2;
+DELETE FROM t2;
+
+--echo
+REPLACE INTO t2 SELECT * FROM t2_data;
+REPLACE INTO v2 SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
+
+--echo
+SELECT * FROM t2;
+DELETE FROM t2;
 
 --echo
 --echo #   - All columns + NULL-value for NOT NULL column.
@@ -696,6 +1025,15 @@ INSERT INTO v1(a, b) SELECT a * 10, b *
 
 --echo
 SELECT * FROM t1;
+DELETE FROM t1;
+
+--echo
+REPLACE INTO t1(a, b) SELECT * FROM t1_data;
+REPLACE INTO v1(a, b) SELECT a * 10, b * 10 FROM t1_data;
+
+--echo
+SELECT * FROM t1;
+DELETE FROM t1;
 
 --echo
 INSERT INTO t2(a, b, c, d) SELECT * FROM t2_data;
@@ -703,6 +1041,15 @@ INSERT INTO v2(a, b, c, d) SELECT a * 10
 
 --echo
 SELECT * FROM t2;
+DELETE FROM t2;
+
+--echo
+REPLACE INTO t2(a, b, c, d) SELECT * FROM t2_data;
+REPLACE INTO v2(a, b, c, d) SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
+
+--echo
+SELECT * FROM t2;
+DELETE FROM t2;
 
 --echo
 --echo #   - Single nullable column, no values for NOT NULL columns.
@@ -714,6 +1061,15 @@ INSERT INTO v1(a) SELECT a * 100 FROM t1
 
 --echo
 SELECT * FROM t1;
+DELETE FROM t1;
+
+--echo
+REPLACE INTO t1(a) SELECT a FROM t1_data;
+REPLACE INTO v1(a) SELECT a * 100 FROM t1_data;
+
+--echo
+SELECT * FROM t1;
+DELETE FROM t1;
 
 --echo
 INSERT INTO t2(a) SELECT a FROM t2_data;
@@ -721,9 +1077,14 @@ INSERT INTO v2(a) SELECT a * 100 FROM t2
 
 --echo
 SELECT * FROM t2;
+DELETE FROM t2;
 
 --echo
-DELETE FROM t1;
+REPLACE INTO t2(a) SELECT a FROM t2_data;
+REPLACE INTO v2(a) SELECT a * 100 FROM t2_data;
+
+--echo
+SELECT * FROM t2;
 DELETE FROM t2;
 
 --echo
@@ -777,6 +1138,15 @@ SELECT * FROM t1;
 
 --echo
 --error ER_BAD_NULL_ERROR
+REPLACE INTO t1 VALUES (1, NULL);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v1 VALUES (1, NULL);
+
+--echo
+SELECT * FROM t1;
+
+--echo
+--error ER_BAD_NULL_ERROR
 INSERT INTO t2 VALUES (1, 2, NULL, 4);
 --error ER_BAD_NULL_ERROR
 INSERT INTO v2 VALUES (1, 2, NULL, 4);
@@ -785,6 +1155,15 @@ INSERT INTO v2 VALUES (1, 2, NULL, 4);
 SELECT * FROM t2;
 
 --echo
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t2 VALUES (1, 2, NULL, 4);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v2 VALUES (1, 2, NULL, 4);
+
+--echo
+SELECT * FROM t2;
+
+--echo
 --echo #   - All columns + NULL-value for NOT NULL column.
 
 --echo
@@ -798,6 +1177,15 @@ SELECT * FROM t1;
 
 --echo
 --error ER_BAD_NULL_ERROR
+REPLACE INTO v1(a, b) VALUES (1, NULL);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a, b) VALUES (1, NULL);
+
+--echo
+SELECT * FROM t1;
+
+--echo
+--error ER_BAD_NULL_ERROR
 INSERT INTO t2(a, b, c, d) VALUES (1, 2, NULL, 4);
 --error ER_BAD_NULL_ERROR
 INSERT INTO v2(a, b, c, d) VALUES (1, 2, NULL, 4);
@@ -806,6 +1194,15 @@ INSERT INTO v2(a, b, c, d) VALUES (1, 2,
 SELECT * FROM t2;
 
 --echo
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t2(a, b, c, d) VALUES (1, 2, NULL, 4);
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v2(a, b, c, d) VALUES (1, 2, NULL, 4);
+
+--echo
+SELECT * FROM t2;
+
+--echo
 --echo #   - Single nullable column, no values for NOT NULL columns.
 
 --echo
@@ -820,6 +1217,21 @@ INSERT INTO v1(a) VALUES (6), (7), (8);
 
 --echo
 SELECT * FROM t1;
+DELETE FROM t1;
+
+--echo
+--error ER_NO_DEFAULT_FOR_FIELD
+REPLACE INTO t1(a) VALUES (1);
+--error ER_NO_DEFAULT_FOR_FIELD
+REPLACE INTO t1(a) VALUES (2), (3), (4);
+--error ER_NO_DEFAULT_FOR_VIEW_FIELD
+REPLACE INTO v1(a) VALUES (5);
+--error ER_NO_DEFAULT_FOR_VIEW_FIELD
+REPLACE INTO v1(a) VALUES (6), (7), (8);
+
+--echo
+SELECT * FROM t1;
+DELETE FROM t1;
 
 --echo
 --error ER_NO_DEFAULT_FOR_FIELD
@@ -833,9 +1245,20 @@ INSERT INTO v2(a) VALUES (6), (7), (8);
 
 --echo
 SELECT * FROM t2;
+DELETE FROM t2;
 
 --echo
-DELETE FROM t1;
+--error ER_NO_DEFAULT_FOR_FIELD
+REPLACE INTO t2(a) VALUES (1);
+--error ER_NO_DEFAULT_FOR_FIELD
+REPLACE INTO t2(a) VALUES (2), (3), (4);
+--error ER_NO_DEFAULT_FOR_VIEW_FIELD
+REPLACE INTO v2(a) VALUES (5);
+--error ER_NO_DEFAULT_FOR_VIEW_FIELD
+REPLACE INTO v2(a) VALUES (6), (7), (8);
+
+--echo
+SELECT * FROM t2;
 DELETE FROM t2;
 
 --echo
@@ -856,10 +1279,19 @@ INSERT INTO v1 SELECT a * 10, b * 10 FRO
 --echo # The following SELECT output should have 4 rows.
 --echo # t1's engine is MyISAM, so the transaction can not be fully rolled back.
 SELECT * FROM t1;
+DELETE FROM t1;
 
 --echo
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1 SELECT * FROM t1_data;
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v1 SELECT a * 10, b * 10 FROM t1_data;
+
+--echo
+--echo # The following SELECT output should have 4 rows.
+--echo # t1's engine is MyISAM, so the transaction can not be fully rolled back.
+SELECT * FROM t1;
 DELETE FROM t1;
-DELETE FROM t2;
 
 --echo
 --echo #   - No column list (all columns) + NULL-value for NOT NULL column.
@@ -872,9 +1304,19 @@ INSERT INTO v2 SELECT a * 10, b * 10, c
 --echo # The following SELECT output should have 4 rows.
 --echo # t2's engine is MyISAM, so the transaction can not be fully rolled back.
 SELECT * FROM t2;
+DELETE FROM t2;
 
 --echo
-DELETE FROM t1;
+--echo #   - No column list (all columns) + NULL-value for NOT NULL column.
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t2 SELECT * FROM t2_data;
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v2 SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
+
+--echo
+--echo # The following SELECT output should have 4 rows.
+--echo # t2's engine is MyISAM, so the transaction can not be fully rolled back.
+SELECT * FROM t2;
 DELETE FROM t2;
 
 --echo
@@ -890,10 +1332,19 @@ INSERT INTO v1(a, b) SELECT a * 10, b *
 --echo # The following SELECT output should have 4 rows.
 --echo # t1's engine is MyISAM, so the transaction can not be fully rolled back.
 SELECT * FROM t1;
+DELETE FROM t1;
 
 --echo
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t1(a, b) SELECT * FROM t1_data;
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v1(a, b) SELECT a * 10, b * 10 FROM t1_data;
+
+--echo
+--echo # The following SELECT output should have 4 rows.
+--echo # t1's engine is MyISAM, so the transaction can not be fully rolled back.
+SELECT * FROM t1;
 DELETE FROM t1;
-DELETE FROM t2;
 
 --echo
 --error ER_BAD_NULL_ERROR
@@ -905,9 +1356,18 @@ INSERT INTO v2(a, b, c, d) SELECT a * 10
 --echo # The following SELECT output should have 4 rows.
 --echo # t2's engine is MyISAM, so the transaction can not be fully rolled back.
 SELECT * FROM t2;
+DELETE FROM t2;
 
 --echo
-DELETE FROM t1;
+--error ER_BAD_NULL_ERROR
+REPLACE INTO t2(a, b, c, d) SELECT * FROM t2_data;
+--error ER_BAD_NULL_ERROR
+REPLACE INTO v2(a, b, c, d) SELECT a * 10, b * 10, c * 10, d * 10 FROM t2_data;
+
+--echo
+--echo # The following SELECT output should have 4 rows.
+--echo # t2's engine is MyISAM, so the transaction can not be fully rolled back.
+SELECT * FROM t2;
 DELETE FROM t2;
 
 --echo
@@ -922,10 +1382,18 @@ INSERT INTO v1(a) SELECT a * 100 FROM t1
 --echo
 --echo # The following SELECT output should have 0 rows.
 SELECT * FROM t1;
+DELETE FROM t1;
+
+--echo
+--error ER_NO_DEFAULT_FOR_FIELD
+REPLACE INTO t1(a) SELECT a FROM t1_data;
+--error ER_NO_DEFAULT_FOR_VIEW_FIELD
+REPLACE INTO v1(a) SELECT a * 100 FROM t1_data;
 
 --echo
+--echo # The following SELECT output should have 0 rows.
+SELECT * FROM t1;
 DELETE FROM t1;
-DELETE FROM t2;
 
 --echo
 --error ER_NO_DEFAULT_FOR_FIELD
@@ -936,9 +1404,17 @@ INSERT INTO v2(a) SELECT a * 100 FROM t2
 --echo
 --echo # The following SELECT output should have 0 rows.
 SELECT * FROM t2;
+DELETE FROM t2;
 
 --echo
-DELETE FROM t1;
+--error ER_NO_DEFAULT_FOR_FIELD
+REPLACE INTO t2(a) SELECT a FROM t2_data;
+--error ER_NO_DEFAULT_FOR_VIEW_FIELD
+REPLACE INTO v2(a) SELECT a * 100 FROM t2_data;
+
+--echo
+--echo # The following SELECT output should have 0 rows.
+SELECT * FROM t2;
 DELETE FROM t2;
 
 --echo

=== modified file 'sql/field.cc'
--- a/sql/field.cc	2012-10-02 09:31:52 +0000
+++ b/sql/field.cc	2012-10-04 15:10:05 +0000
@@ -1360,7 +1360,7 @@ Field::Field(uchar *ptr_arg,uint32 lengt
    unireg_check(unireg_check_arg),
    field_length(length_arg), null_bit(null_bit_arg), 
    is_created_from_null_item(FALSE),
-   field_warning_was_pushed(0)
+   m_warnings_pushed(0)
 {
   flags=real_maybe_null() ? 0: NOT_NULL_FLAG;
   comment.str= (char*) "";
@@ -1442,21 +1442,22 @@ void Field::set_null(my_ptrdiff_t row_of
   }
   else if (is_tmp_nullable())
   {
-    set_tmp_null();
-//    m_is_tmp_null= true;
-//    m_count_cuted_fields_saved= table->in_use->count_cuted_fields;
+    set_tmp_null(true);
   }
 }
 
-void Field::reset_tmp_null()
-{
-  m_is_tmp_null= false;
-}
 
-void Field::set_tmp_null()
+/**
+  TODO [alik] comment is needed.
+*/
+void Field::set_tmp_null(bool tmp_null)
 {
-  m_is_tmp_null= true;
-  m_count_cuted_fields_saved= table->in_use->count_cuted_fields;
+  m_is_tmp_null= tmp_null;
+
+  if (m_is_tmp_null)
+    // TODO [alik] Why are we so sure table->in_use is always set here?
+    // (In other places we choose between current_thd and table->in_use)
+    m_count_cuted_fields_saved= table->in_use->count_cuted_fields;
 }
 
 
@@ -1474,7 +1475,7 @@ void Field::set_notnull(my_ptrdiff_t row
   }
   else if (is_tmp_nullable())
   {
-    m_is_tmp_null= false;
+    set_tmp_null(false);
   }
 }
 
@@ -10574,69 +10575,88 @@ uint32 Field_blob::max_display_length()
     0 otherwise
 */
 
-bool 
-Field::set_warning(Sql_condition::enum_warning_level level, uint code,
-                   int cut_increment)
+bool Field::set_warning(Sql_condition::enum_warning_level level,
+                        uint code,
+                        int cut_increment)
 {
   return set_warning(level, code, cut_increment, NULL, NULL);
 }
 
 
-bool
-Field::set_warning(Sql_condition::enum_warning_level level, uint code,
-                   int cut_increment, const char *view_db,
-                   const char *view_name)
+/**
+  Produce warning or note about data saved into field.
+
+  TODO
+*/
+
+bool Field::set_warning(Sql_condition::enum_warning_level level,
+                        uint code,
+                        int cut_increment,
+                        const char *view_db_name,
+                        const char *view_name)
 {
   /*
     If this field was created only for type conversion purposes it
     will have table == NULL.
   */
+
   THD *thd= table ? table->in_use : current_thd;
-  if (thd->count_cuted_fields)
+
+  if (!thd->count_cuted_fields)
+    return level >= Sql_condition::WARN_LEVEL_WARN;
+
+  thd->cuted_fields+= cut_increment;
+
+  if (thd->lex->sql_command != SQLCOM_INSERT &&
+      thd->lex->sql_command != SQLCOM_INSERT_SELECT &&
+      thd->lex->sql_command != SQLCOM_REPLACE &&
+      thd->lex->sql_command != SQLCOM_REPLACE_SELECT)
   {
-    thd->cuted_fields+= cut_increment;
-    if ((thd->lex->sql_command == SQLCOM_INSERT ||
-         thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
-         thd->lex->sql_command == SQLCOM_REPLACE) ||
-         thd->lex->sql_command == SQLCOM_REPLACE_SELECT)
-    {
-      unsigned bitmask;
-      if ((code == ER_BAD_NULL_ERROR && (bitmask= BAD_NULL_ERROR_PUSHED)) ||
-          (code == ER_WARN_NULL_TO_NOTNULL &&
-           (bitmask= WARN_NULL_TO_NOTNULL_PUSHED)) ||
-          (code == ER_NO_DEFAULT_FOR_FIELD &&
-           (bitmask= NO_DEFAULT_FOR_FIELD_PUSHED)))
-      {
-        if (!(field_warning_was_pushed & bitmask))
-        {
-          push_warning_printf(thd, level, code, ER(code), field_name,
-                              thd->get_stmt_da()->current_row_for_warning());
-          field_warning_was_pushed|= bitmask;
-        }
-      }
-      else if (code == ER_NO_DEFAULT_FOR_VIEW_FIELD)
-      {
-        if (!(field_warning_was_pushed & NO_DEFAULT_FOR_VIEW_FIELD_PUSHED))
-        {
-          push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
-                              ER_NO_DEFAULT_FOR_VIEW_FIELD,
-                              ER(ER_NO_DEFAULT_FOR_VIEW_FIELD),
-                              view_db,
-                              view_name);
-          field_warning_was_pushed|= NO_DEFAULT_FOR_VIEW_FIELD_PUSHED;
-        }
-      }
-      else
-        push_warning_printf(thd, level, code, ER(code), field_name,
-                            thd->get_stmt_da()->current_row_for_warning());
-    }
-    else
-      push_warning_printf(thd, level, code, ER(code), field_name,
-                          thd->get_stmt_da()->current_row_for_warning());
+    // We aggregate warnings from only INSERT and REPLACE statements.
+
+    push_warning_printf(thd, level, code, ER(code), field_name,
+                        thd->get_stmt_da()->current_row_for_warning());
 
     return 0;
   }
-  return level >= Sql_condition::WARN_LEVEL_WARN;
+
+  unsigned int current_warning_mask= 0;
+
+  if (code == ER_BAD_NULL_ERROR)
+    current_warning_mask= BAD_NULL_ERROR_PUSHED;
+  else if (code == ER_WARN_NULL_TO_NOTNULL)
+    current_warning_mask= WARN_NULL_TO_NOTNULL_PUSHED;
+  else if (code == ER_NO_DEFAULT_FOR_FIELD)
+    current_warning_mask= NO_DEFAULT_FOR_FIELD_PUSHED;
+
+  if (current_warning_mask)
+  {
+    if (!(m_warnings_pushed & current_warning_mask))
+    {
+      push_warning_printf(thd, level, code, ER(code), field_name,
+                          thd->get_stmt_da()->current_row_for_warning());
+      m_warnings_pushed|= current_warning_mask;
+    }
+  }
+  else if (code == ER_NO_DEFAULT_FOR_VIEW_FIELD)
+  {
+    if (!(m_warnings_pushed & NO_DEFAULT_FOR_VIEW_FIELD_PUSHED))
+    {
+      push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+                          ER_NO_DEFAULT_FOR_VIEW_FIELD,
+                          ER(ER_NO_DEFAULT_FOR_VIEW_FIELD),
+                          view_db_name,
+                          view_name);
+      m_warnings_pushed|= NO_DEFAULT_FOR_VIEW_FIELD_PUSHED;
+    }
+  }
+  else
+  {
+    push_warning_printf(thd, level, code, ER(code), field_name,
+                        thd->get_stmt_da()->current_row_for_warning());
+  }
+
+  return 0;
 }
 
 

=== modified file 'sql/field.h'
--- a/sql/field.h	2012-10-01 03:34:26 +0000
+++ b/sql/field.h	2012-10-04 15:10:05 +0000
@@ -568,50 +568,51 @@ public:
   bool is_created_from_null_item;
 
 private:
-  unsigned field_warning_was_pushed;
-  enum pushed_warns_mask_e {BAD_NULL_ERROR_PUSHED= 1,
-                            WARN_NULL_TO_NOTNULL_PUSHED= 2,
-                            NO_DEFAULT_FOR_FIELD_PUSHED= 4,
-                            NO_DEFAULT_FOR_VIEW_FIELD_PUSHED= 8};
-
-public:
-  void reset_warning_flag()
+  enum enum_pushed_warnings
   {
-    field_warning_was_pushed= 0;
-  }
+    BAD_NULL_ERROR_PUSHED= 1,
+    WARN_NULL_TO_NOTNULL_PUSHED= 2,
+    NO_DEFAULT_FOR_FIELD_PUSHED= 4,
+    NO_DEFAULT_FOR_VIEW_FIELD_PUSHED= 8
+  };
+
+  // TODO [alik] -- write a comment, like this:
+  // Bitmap specifying which warnings have been already pushed.
+  // Uses enum_pushed_warnings.
+  unsigned int m_warnings_pushed;
 
+public:
   Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
         uchar null_bit_arg, utype unireg_check_arg,
         const char *field_name_arg);
-  virtual ~Field() {}
+
+  virtual ~Field()
+  { }
+
+  void reset_warnings()
+  { m_warnings_pushed= 0; }
 
   /**
     Turn on/off temporary nullability for the field.
-
-    @param is_tmp_nullable    NULLability flag:
-                                  true - turn on temporary NULLability
-                                  false - turn off temporary NULLability
   */
   void set_tmp_nullable(bool is_tmp_nullable)
   { m_is_tmp_nullable= is_tmp_nullable; }
 
-  void reset_tmp_null();
-  void set_tmp_null();
+  void set_tmp_null(bool tmp_null);
 
   /**
-    Return temporary NULLability flag.
-
-    @return    true - if NULL can be assigned temporary to the Field
-               false - if NULL can not be assigned temporary to the Field
+    @return temporary NULL-ability flag.
+    @retval true if NULL can be assigned temporary to the Field.
+    @retval false if NULL can not be assigned even temporary to the Field.
   */
   bool is_tmp_nullable() const
   { return m_is_tmp_nullable; }
 
   /**
-    Check whether Field has temporary value NULL.
-
-    @return    true - if the Field has temporary value NULL
-               false - if the Field's value is NOT NULL
+    @return whether Field has temporary value NULL.
+    @retval true if the Field has temporary value NULL.
+    @retval false if the Field's value is NOT NULL, or if the temporary
+    NULL-ability flag is reset.
   */
   bool is_tmp_null() const
   { return is_tmp_nullable() && m_is_tmp_null; }

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2012-09-26 07:11:12 +0000
+++ b/sql/sql_base.cc	2012-10-04 15:10:05 +0000
@@ -8970,7 +8970,7 @@ fill_record_n_invoke_before_triggers(THD
                                      List<Item> &values, bool ignore_errors,
                                      Table_triggers_list *triggers,
                                      enum trg_event_type event,
-                                     uint bitmap_size)
+                                     int num_fields)
 {
   if (triggers)
     triggers->enable_fields_temporary_nullability(thd);
@@ -8985,11 +8985,13 @@ fill_record_n_invoke_before_triggers(THD
 
   if (triggers && event == TRG_EVENT_INSERT &&
       (thd->lex->sql_command == SQLCOM_INSERT ||
-       thd->lex->sql_command == SQLCOM_INSERT_SELECT))
+       thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
+       thd->lex->sql_command == SQLCOM_REPLACE ||
+       thd->lex->sql_command == SQLCOM_REPLACE_SELECT))
   {
-    DBUG_ASSERT(bitmap_size);
+    DBUG_ASSERT(num_fields);
 
-    bitmap_init(&insert_into_fields_bitmap, NULL, bitmap_size, false);
+    bitmap_init(&insert_into_fields_bitmap, NULL, num_fields, false);
     rc= fill_record(thd, fields, values, ignore_errors, NULL,
                     &insert_into_fields_bitmap);
   }
@@ -9010,7 +9012,9 @@ fill_record_n_invoke_before_triggers(THD
   {
     if (event == TRG_EVENT_INSERT &&
         (thd->lex->sql_command == SQLCOM_INSERT ||
-         thd->lex->sql_command == SQLCOM_INSERT_SELECT))
+         thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
+         thd->lex->sql_command == SQLCOM_REPLACE ||
+         thd->lex->sql_command == SQLCOM_REPLACE_SELECT))
     {
       TABLE *tbl= triggers->trigger_table;
 
@@ -9019,7 +9023,7 @@ fill_record_n_invoke_before_triggers(THD
         if (((*f)->flags & NO_DEFAULT_VALUE_FLAG) &&
             !bitmap_is_set(&insert_into_fields_bitmap, (*f)->field_index))
         {
-          (*f)->set_tmp_null();
+          (*f)->set_tmp_null(true);
         }
       }
     }
@@ -9137,7 +9141,7 @@ fill_record_n_invoke_before_triggers(THD
                                      List<Item> &values, bool ignore_errors,
                                      Table_triggers_list *triggers,
                                      enum trg_event_type event,
-                                     uint bitmap_size)
+                                     int num_fields)
 {
   if (triggers)
     triggers->enable_fields_temporary_nullability(thd);
@@ -9152,11 +9156,13 @@ fill_record_n_invoke_before_triggers(THD
 
   if (triggers && event == TRG_EVENT_INSERT &&
       (thd->lex->sql_command == SQLCOM_INSERT ||
-       thd->lex->sql_command == SQLCOM_INSERT_SELECT))
+       thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
+       thd->lex->sql_command == SQLCOM_REPLACE ||
+       thd->lex->sql_command == SQLCOM_REPLACE_SELECT))
   {
-    DBUG_ASSERT(bitmap_size);
+    DBUG_ASSERT(num_fields);
 
-    bitmap_init(&insert_into_fields_bitmap, NULL, bitmap_size, false);
+    bitmap_init(&insert_into_fields_bitmap, NULL, num_fields, false);
 
     rc= fill_record(thd, ptr, values, ignore_errors, NULL,
                     &insert_into_fields_bitmap);
@@ -9178,7 +9184,9 @@ fill_record_n_invoke_before_triggers(THD
   {
     if (event == TRG_EVENT_INSERT &&
         (thd->lex->sql_command == SQLCOM_INSERT ||
-         thd->lex->sql_command == SQLCOM_INSERT_SELECT))
+         thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
+         thd->lex->sql_command == SQLCOM_REPLACE ||
+         thd->lex->sql_command == SQLCOM_REPLACE_SELECT))
     {
       TABLE *tbl= triggers->trigger_table;
 
@@ -9187,7 +9195,7 @@ fill_record_n_invoke_before_triggers(THD
         if (((*f)->flags & NO_DEFAULT_VALUE_FLAG) &&
             !bitmap_is_set(&insert_into_fields_bitmap, (*f)->field_index))
         {
-          (*f)->set_tmp_null();
+          (*f)->set_tmp_null(true);
         }
       }
     }

=== modified file 'sql/sql_base.h'
--- a/sql/sql_base.h	2012-09-26 07:11:12 +0000
+++ b/sql/sql_base.h	2012-10-04 15:09:42 +0000
@@ -170,13 +170,13 @@ bool fill_record_n_invoke_before_trigger
                                           bool ignore_errors,
                                           Table_triggers_list *triggers,
                                           enum trg_event_type event,
-                                          uint bitmap_size);
+                                          int num_fields);
 bool fill_record_n_invoke_before_triggers(THD *thd, Field **field,
                                           List<Item> &values,
                                           bool ignore_errors,
                                           Table_triggers_list *triggers,
                                           enum trg_event_type event,
-                                          uint bitmap_size);
+                                          int num_fields);
 bool insert_fields(THD *thd, Name_resolution_context *context,
 		   const char *db_name, const char *table_name,
                    List_iterator<Item> *it, bool any_privileges);

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2012-09-13 09:22:26 +0000
+++ b/sql/sql_class.h	2012-10-04 15:08:40 +0000
@@ -4138,6 +4138,171 @@ public:
   bool send_data(List<Item> &items);
 };
 
+/**
+   @todo This class is declared in sql_class.h, but the members are defined in
+   sql_insert.cc. It is very confusing that a class is defined in a file with
+   a different name than the file where it is declared.
+*/
+class select_insert :public select_result_interceptor {
+public:
+  TABLE_LIST *table_list;
+  TABLE *table;
+private:
+  /**
+     The columns of the table to be inserted into, *or* the columns of the
+     table from which values are selected. For legacy reasons both are
+     allowed.
+   */
+  List<Item> *fields;
+public:
+  ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not
+  COPY_INFO info;
+  COPY_INFO update; ///< the UPDATE part of "info"
+  bool insert_into_view;
+
+  /**
+     Creates a select_insert for routing a result set to an existing
+     table.
+
+     @param table_list_par   The table reference for the destination table.
+     @param table_par        The destination table. May be NULL.
+     @param target_columns   The columns of the table which is the target for
+                             insertion. May be NULL, but if not, the same
+                             value must be used for target_or_source_columns.
+     @param target_or_source_columns The columns of the source table providing
+                             data, or columns of the target table. If the
+                             target table is known, the columns of that table
+                             should be used. If the target table is not known
+                             (it may not yet exist), the columns of the source
+                             table should be used, and target_columns should
+                             be NULL.
+     @param update_fields    The columns to be updated in case of duplicate
+                             keys. May be NULL.
+     @param update_values    The values to be assigned in case of duplicate
+                             keys. May be NULL.
+     @param duplicate        The policy for handling duplicates.
+     @param ignore           How the insert operation is to handle certain
+                             errors. See COPY_INFO.
+
+     @todo This constructor takes 8 arguments, 6 of which are used to
+     immediately construct a COPY_INFO object. Obviously the constructor
+     should take the COPY_INFO object as argument instead. Also, some
+     select_insert members initialized here are totally redundant, as they are
+     found inside the COPY_INFO.
+
+     Here is the explanation of how we set the manage_defaults parameter of
+     info's constructor below.
+     @li if target_columns==NULL, the statement is
+@verbatim
+     CREATE TABLE a_table (possibly some columns1) SELECT columns2
+@endverbatim
+     which sets all of a_table's columns2 to values returned by SELECT (no
+     default needs to be set); a_table's columns1 get set from defaults
+     prepared by make_empty_rec() when table is created, not by COPY_INFO. So
+     manage_defaults is "false".
+     @li otherwise, target_columns!=NULL and so it is INSERT SELECT. If there
+     are explicitely listed columns like
+@verbatim
+     INSERT INTO a_table (columns1) SELECT ...
+@verbatim
+     then non-listed columns (columns of a_table which are not columns1) may
+     need a default set by COPY_INFO so manage_defaults is "true". If no
+     column is explicitely listed, all columns will be set to values returned
+     by SELECT, so "manage_defaults" is false.
+  */
+  select_insert(TABLE_LIST *table_list_par,
+                TABLE *table_par,
+                List<Item> *target_columns,
+                List<Item> *target_or_source_columns,
+                List<Item> *update_fields,
+                List<Item> *update_values,
+                enum_duplicates duplic,
+                bool ignore)
+    :table_list(table_list_par),
+     table(table_par),
+     fields(target_or_source_columns),
+     autoinc_value_of_last_inserted_row(0),
+     info(COPY_INFO::INSERT_OPERATION,
+          target_columns,
+          // manage_defaults
+          target_columns != NULL && target_columns->elements != 0,
+          duplic,
+          ignore),
+     update(COPY_INFO::UPDATE_OPERATION,
+            update_fields,
+            update_values),
+     insert_into_view(table_list_par && table_list_par->view != 0)
+  {
+    DBUG_ASSERT(target_or_source_columns != NULL);
+    DBUG_ASSERT(target_columns == target_or_source_columns ||
+                target_columns == NULL);
+  }
+
+
+public:
+  ~select_insert();
+  int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
+  virtual int prepare2(void);
+  bool send_data(List<Item> &items);
+  virtual void store_values(List<Item> &values);
+  void send_error(uint errcode,const char *err);
+  bool send_eof();
+  virtual void abort_result_set();
+  /* not implemented: select_insert is never re-used in prepared statements */
+  void cleanup();
+};
+
+
+/**
+   @todo This class inherits a class which is non-abstract. This is not in
+   line with good programming practices and the inheritance should be broken
+   up. Also, the class is declared in sql_class.h, but defined sql_insert.cc
+   which is confusing.
+*/
+class select_create: public select_insert {
+  ORDER *group;
+  TABLE_LIST *create_table;
+  HA_CREATE_INFO *create_info;
+  TABLE_LIST *select_tables;
+  Alter_info *alter_info;
+  Field **field;
+  /* lock data for tmp table */
+  MYSQL_LOCK *m_lock;
+  /* m_lock or thd->extra_lock */
+  MYSQL_LOCK **m_plock;
+public:
+  select_create (TABLE_LIST *table_arg,
+		 HA_CREATE_INFO *create_info_par,
+                 Alter_info *alter_info_arg,
+		 List<Item> &select_fields,enum_duplicates duplic, bool ignore,
+                 TABLE_LIST *select_tables_arg)
+    :select_insert (NULL, // table_list_par
+                    NULL, // table_par
+                    NULL, // target_columns
+                    &select_fields,
+                    NULL, // update_fields
+                    NULL, // update_values
+                    duplic,
+                    ignore),
+     create_table(table_arg),
+     create_info(create_info_par),
+     select_tables(select_tables_arg),
+     alter_info(alter_info_arg),
+     m_plock(NULL)
+  {}
+  int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
+
+  int binlog_show_create_table(TABLE **tables, uint count);
+  void store_values(List<Item> &values);
+  void send_error(uint errcode,const char *err);
+  bool send_eof();
+  virtual void abort_result_set();
+
+  // Needed for access from local class MY_HOOKS in prepare(), since thd is proteted.
+  const THD *get_thd(void) { return thd; }
+  const HA_CREATE_INFO *get_create_info() { return create_info; };
+  int prepare2(void);
+};
 
 #include <myisam.h>
 

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2012-10-02 09:31:52 +0000
+++ b/sql/sql_insert.cc	2012-10-04 15:10:05 +0000
@@ -612,20 +612,20 @@ create_insert_stmt_from_insert_delayed(T
 /**
    Wrapper for invocation of function check_that_all_fields_are_given_value.
 
-   @param[in] thd                 Thread handler
-   @param[in] table               Table to insert into
-   @param[in] table_list          Table list
-   @param[in]  abort_on_warning   Whether to report an error or a warning
-                                  if some INSERT field is not assigned.
+   @param[in] thd               Thread handler
+   @param[in] table             Table to insert into
+   @param[in] table_list        Table list
+   @param[in] abort_on_warning  Whether to report an error or a warning
+                                if some INSERT field is not assigned.
 
   @return Operation status.
     @retval false   Success
     @retval true    Failure
  */
-static bool
-safely_check_that_all_fields_are_given_values(THD* thd, TABLE* table,
-                                              TABLE_LIST* table_list,
-                                              bool abort_on_warning)
+static bool safely_check_that_all_fields_are_given_values(
+  THD* thd, TABLE* table,
+  TABLE_LIST* table_list,
+  bool abort_on_warning)
 {
   bool saved_abort_on_warning= thd->abort_on_warning;
   thd->abort_on_warning= abort_on_warning;
@@ -640,17 +640,19 @@ safely_check_that_all_fields_are_given_v
 
 /**
   This method cleans up internal structures allocated during running
-  function mysql_insert().
+  function mysql_insert(). It must be used with mysql_insert() only.
 */
-inline static void cleanup_after_error(THD *thd, bool joins_freed,
-                                       thr_lock_type lock_type)
+inline static void mysql_insert_cleanup_after_error(THD *thd, bool joins_freed,
+                                                    thr_lock_type lock_type)
 {
 #ifndef EMBEDDED_LIBRARY
   if (lock_type == TL_WRITE_DELAYED)
     end_delayed_insert(thd);
 #endif
+
   if (!joins_freed)
     free_underlaid_joins(thd, &thd->lex->select_lex);
+
   thd->abort_on_warning= 0;
 }
 
@@ -769,7 +771,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
                             table_list->view != 0),
                            !ignore && thd->is_strict_mode()))
   {
-    cleanup_after_error(thd, joins_freed, lock_type);
+    mysql_insert_cleanup_after_error(thd, joins_freed, lock_type);
     DBUG_RETURN(true);
   }
 
@@ -778,13 +780,13 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   /* Must be done before can_prune_insert, due to internal initialization. */
   if (info.add_function_default_columns(table, table->write_set))
   {
-    cleanup_after_error(thd, joins_freed, lock_type);
+    mysql_insert_cleanup_after_error(thd, joins_freed, lock_type);
     DBUG_RETURN(true);
   }
   if (duplic == DUP_UPDATE &&
       update.add_function_default_columns(table, table->write_set))
   {
-    cleanup_after_error(thd, joins_freed, lock_type);
+    mysql_insert_cleanup_after_error(thd, joins_freed, lock_type);
     DBUG_RETURN(true);
   }
 
@@ -821,7 +823,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
                                            &prune_needs_default_values,
                                            &used_partitions))
     {
-      cleanup_after_error(thd, joins_freed, lock_type);
+      mysql_insert_cleanup_after_error(thd, joins_freed, lock_type);
       DBUG_RETURN(true);
     }
 
@@ -857,12 +859,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
     if (values->elements != value_count)
     {
       my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
-      cleanup_after_error(thd, joins_freed, lock_type);
+      mysql_insert_cleanup_after_error(thd, joins_freed, lock_type);
       DBUG_RETURN(true);
     }
     if (setup_fields(thd, Ref_ptr_array(), *values, MARK_COLUMNS_READ, 0, 0))
     {
-      cleanup_after_error(thd, joins_freed, lock_type);
+      mysql_insert_cleanup_after_error(thd, joins_freed, lock_type);
       DBUG_RETURN(true);
     }
 
@@ -911,7 +913,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
     */
 
     err= explain_no_table(thd, "No tables used");
-    cleanup_after_error(thd, joins_freed, lock_type);
+    mysql_insert_cleanup_after_error(thd, joins_freed, lock_type);
     DBUG_RETURN(err);
   }
 
@@ -962,7 +964,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
        table->next_number_field != NULL &&
        rpl_master_has_bug(active_mi->rli, 24432, TRUE, NULL, NULL))
     {
-      cleanup_after_error(thd, joins_freed, lock_type);
+      mysql_insert_cleanup_after_error(thd, joins_freed, lock_type);
       DBUG_RETURN(true);
     }
   }
@@ -1014,7 +1016,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
 
   for (Field** next_field= table->field; *next_field; ++next_field)
   {
-    (*next_field)->reset_warning_flag();
+    (*next_field)->reset_warnings();
   }
 
   while ((values= its++))
@@ -1022,6 +1024,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
     if (fields.elements || !value_count)
     {
       restore_record(table,s->default_values);	// Get empty record
+
       if (fill_record_n_invoke_before_triggers(thd, fields, *values, 0,
                                                table->triggers,
                                                TRG_EVENT_INSERT,
@@ -1040,26 +1043,22 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
 	error=1;
 	break;
       }
-      {
-        TABLE *t= table;
-        if (!t)
-          t= context->table_list->table;
-        bool abort_on_warning= !ignore && thd->is_strict_mode();
-        res= safely_check_that_all_fields_are_given_values(thd, t,
-                                                           context->table_list,
-                                                           abort_on_warning);
 
-        if (res)
+      res= safely_check_that_all_fields_are_given_values(
+        thd,
+        table ? table : context->table_list->table,
+        context->table_list,
+        !ignore && thd->is_strict_mode());
+
+      if (res)
+      {
+        if (values_list.elements != 1 && !thd->is_error())
         {
-          if (values_list.elements != 1 && ! thd->is_error())
-          {
-            info.stats.records++;
-            continue;
-          }
-          error=1;
-          break;
+          info.stats.records++;
+          continue;
         }
-
+        error= 1;
+        break;
       }
     }
     else
@@ -1263,7 +1262,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
 
   if (error)
   {
-    cleanup_after_error(thd, joins_freed, lock_type);
+    mysql_insert_cleanup_after_error(thd, joins_freed, lock_type);
     DBUG_RETURN(true);
   }
 
@@ -3598,8 +3597,8 @@ select_insert::prepare(List<Item> &value
 
   for (Field** next_field= table->field; *next_field; ++next_field)
   {
-    (*next_field)->reset_warning_flag();
-    (*next_field)->reset_tmp_null();
+    (*next_field)->reset_warnings();
+    (*next_field)->set_tmp_null(false);
   }
 
   DBUG_RETURN(res);

=== modified file 'sql/sql_insert.h'
--- a/sql/sql_insert.h	2012-10-01 03:34:26 +0000
+++ b/sql/sql_insert.h	2012-10-04 15:08:40 +0000
@@ -36,169 +36,6 @@ void upgrade_lock_type_for_insert(THD *t
                                   enum_duplicates duplic,
                                   bool is_multi_insert);
 
-
-class select_insert :public select_result_interceptor {
-public:
-  TABLE_LIST *table_list;
-  TABLE *table;
-private:
-  /**
-     The columns of the table to be inserted into, *or* the columns of the
-     table from which values are selected. For legacy reasons both are
-     allowed.
-   */
-  List<Item> *fields;
-
-public:
-  ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not
-  COPY_INFO info;
-  COPY_INFO update; ///< the UPDATE part of "info"
-  bool insert_into_view;
-
-  /**
-     Creates a select_insert for routing a result set to an existing
-     table.
-
-     @param table_list_par   The table reference for the destination table.
-     @param table_par        The destination table. May be NULL.
-     @param target_columns   The columns of the table which is the target for
-                             insertion. May be NULL, but if not, the same
-                             value must be used for target_or_source_columns.
-     @param target_or_source_columns The columns of the source table providing
-                             data, or columns of the target table. If the
-                             target table is known, the columns of that table
-                             should be used. If the target table is not known
-                             (it may not yet exist), the columns of the source
-                             table should be used, and target_columns should
-                             be NULL.
-     @param update_fields    The columns to be updated in case of duplicate
-                             keys. May be NULL.
-     @param update_values    The values to be assigned in case of duplicate
-                             keys. May be NULL.
-     @param duplicate        The policy for handling duplicates.
-     @param ignore           How the insert operation is to handle certain
-                             errors. See COPY_INFO.
-
-     @todo This constructor takes 8 arguments, 6 of which are used to
-     immediately construct a COPY_INFO object. Obviously the constructor
-     should take the COPY_INFO object as argument instead. Also, some
-     select_insert members initialized here are totally redundant, as they are
-     found inside the COPY_INFO.
-
-     Here is the explanation of how we set the manage_defaults parameter of
-     info's constructor below.
-     @li if target_columns==NULL, the statement is
-@verbatim
-     CREATE TABLE a_table (possibly some columns1) SELECT columns2
-@endverbatim
-     which sets all of a_table's columns2 to values returned by SELECT (no
-     default needs to be set); a_table's columns1 get set from defaults
-     prepared by make_empty_rec() when table is created, not by COPY_INFO. So
-     manage_defaults is "false".
-     @li otherwise, target_columns!=NULL and so it is INSERT SELECT. If there
-     are explicitely listed columns like
-@verbatim
-     INSERT INTO a_table (columns1) SELECT ...
-@verbatim
-     then non-listed columns (columns of a_table which are not columns1) may
-     need a default set by COPY_INFO so manage_defaults is "true". If no
-     column is explicitely listed, all columns will be set to values returned
-     by SELECT, so "manage_defaults" is false.
-  */
-  select_insert(TABLE_LIST *table_list_par,
-                TABLE *table_par,
-                List<Item> *target_columns,
-                List<Item> *target_or_source_columns,
-                List<Item> *update_fields,
-                List<Item> *update_values,
-                enum_duplicates duplic,
-                bool ignore)
-    :table_list(table_list_par),
-     table(table_par),
-     fields(target_or_source_columns),
-     autoinc_value_of_last_inserted_row(0),
-     info(COPY_INFO::INSERT_OPERATION,
-          target_columns,
-          // manage_defaults
-          target_columns != NULL && target_columns->elements != 0,
-          duplic,
-          ignore),
-     update(COPY_INFO::UPDATE_OPERATION,
-            update_fields,
-            update_values),
-     insert_into_view(table_list_par && table_list_par->view != 0)
-  {
-    DBUG_ASSERT(target_or_source_columns != NULL);
-    DBUG_ASSERT(target_columns == target_or_source_columns ||
-                target_columns == NULL);
-  }
-
-
-public:
-  ~select_insert();
-  int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
-  virtual int prepare2(void);
-  bool send_data(List<Item> &items);
-  virtual void store_values(List<Item> &values);
-  void send_error(uint errcode,const char *err);
-  bool send_eof();
-  virtual void abort_result_set();
-  /* not implemented: select_insert is never re-used in prepared statements */
-  void cleanup();
-};
-
-
-/**
-   @todo This class inherits a class which is non-abstract. This is not in
-   line with good programming practices and the inheritance should be broken
-   up.
-*/
-class select_create: public select_insert {
-  ORDER *group;
-  TABLE_LIST *create_table;
-  HA_CREATE_INFO *create_info;
-  TABLE_LIST *select_tables;
-  Alter_info *alter_info;
-  Field **field;
-  /* lock data for tmp table */
-  MYSQL_LOCK *m_lock;
-  /* m_lock or thd->extra_lock */
-  MYSQL_LOCK **m_plock;
-public:
-  select_create (TABLE_LIST *table_arg,
-		 HA_CREATE_INFO *create_info_par,
-                 Alter_info *alter_info_arg,
-		 List<Item> &select_fields,enum_duplicates duplic, bool ignore,
-                 TABLE_LIST *select_tables_arg)
-    :select_insert (NULL, // table_list_par
-                    NULL, // table_par
-                    NULL, // target_columns
-                    &select_fields,
-                    NULL, // update_fields
-                    NULL, // update_values
-                    duplic,
-                    ignore),
-     create_table(table_arg),
-     create_info(create_info_par),
-     select_tables(select_tables_arg),
-     alter_info(alter_info_arg),
-     m_plock(NULL)
-  {}
-  int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
-
-  int binlog_show_create_table(TABLE **tables, uint count);
-  void store_values(List<Item> &values);
-  void send_error(uint errcode,const char *err);
-  bool send_eof();
-  virtual void abort_result_set();
-
-  // Needed for access from local class MY_HOOKS in prepare(), since thd is proteted.
-  const THD *get_thd(void) { return thd; }
-  const HA_CREATE_INFO *get_create_info() { return create_info; };
-  int prepare2(void);
-};
-
-
 int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
                                            TABLE_LIST *table_list);
 void prepare_triggers_for_insert_stmt(TABLE *table);

=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc	2012-10-02 05:35:46 +0000
+++ b/sql/sql_load.cc	2012-10-04 15:10:05 +0000
@@ -266,9 +266,7 @@ int mysql_load(THD *thd,sql_exchange *ex
   table= table_list->table;
 
   for (Field **cur_field= table->field; *cur_field; ++cur_field)
-  {
-    (*cur_field)->reset_warning_flag();
-  }
+    (*cur_field)->reset_warnings();
 
   transactional_table= table->file->has_transactions();
 #ifndef EMBEDDED_LIBRARY
@@ -1102,15 +1100,12 @@ read_sep_field(THD *thd, COPY_INFO &info
       }
     }
 
-    /*
-      Bypass all fields in the table and clear
-      temporary nullability flags for each one.
-    */
-    Item *real_item;
+    // Clear temporary nullability flags for every field in the table.
+
     it.rewind();
     while ((item= it++))
     {
-      real_item= item->real_item();
+      Item *real_item= item->real_item();
       if (real_item->type() == Item::FIELD_ITEM)
         ((Item_field *)real_item)->field->set_tmp_nullable(false);
     }
@@ -1126,14 +1121,17 @@ read_sep_field(THD *thd, COPY_INFO &info
     if (!table->triggers)
     {
       /*
-        If there isn't triggers for the table then bypass all fields
-        in the table and check for NOT NULL constraint for each one.
+        If there is no trigger for the table then check the NOT NULL constraint
+        for every table field.
+
+        TODO [alik] please add here where the constraint is checked if there is
+        a trigger for the table. Or how the constraint is ensured.
       */
       it.rewind();
 
       while ((item= it++))
       {
-        real_item= item->real_item();
+        Item *real_item= item->real_item();
         if (real_item->type() == Item::FIELD_ITEM)
           ((Item_field *) real_item)->field->check_constraints(ER_WARN_NULL_TO_NOTNULL);
       }

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2012-10-01 03:34:26 +0000
+++ b/sql/sql_trigger.cc	2012-10-04 15:10:05 +0000
@@ -2252,11 +2252,12 @@ void Table_triggers_list::enable_fields_
   for (Field** next_field= trigger_table->field; *next_field; ++next_field)
   {
     (*next_field)->set_tmp_nullable(true);
-    if (thd->lex->sql_command != SQLCOM_LOAD)
-    {
-      (*next_field)->reset_tmp_null();
-    }
     (*next_field)->set_count_cuted_fields(thd->count_cuted_fields);
+
+    // TODO [alik] please add a comment about why SQLCOM_LOAD is so special, so
+    // that we don't reset tmp-null for it.
+    if (thd->lex->sql_command != SQLCOM_LOAD)
+      (*next_field)->set_tmp_null(false);
   }
 }
 

=== modified file 'sql/table.h'
--- a/sql/table.h	2012-09-13 09:23:30 +0000
+++ b/sql/table.h	2012-10-04 15:09:42 +0000
@@ -1047,6 +1047,8 @@ public:
   uchar		*null_flags;
   my_bitmap_map	*bitmap_init_value;
   MY_BITMAP     def_read_set, def_write_set, tmp_set; /* containers */
+  // TODO [alik]: why do we need both def_fields_set_during_insert and
+  // fields_set_during_insert.
   MY_BITMAP     def_fields_set_during_insert;
   MY_BITMAP     *read_set, *write_set;          /* Active column sets */
   MY_BITMAP     *fields_set_during_insert;

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (alexander.nozdrin:4223 to 4232) Alexander Nozdrin4 Oct