From: Alexander Nozdrin Date: October 4 2012 3:22pm Subject: bzr push into mysql-trunk branch (alexander.nozdrin:4223 to 4232) List-Archive: http://lists.mysql.com/commits/144949 Message-Id: <20121004152201.3881.74862.4232@quad> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 &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 &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 &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 *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 &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 *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 *target_columns, + List *target_or_source_columns, + List *update_fields, + List *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 &list, SELECT_LEX_UNIT *u); + virtual int prepare2(void); + bool send_data(List &items); + virtual void store_values(List &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 &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 &list, SELECT_LEX_UNIT *u); + + int binlog_show_create_table(TABLE **tables, uint count); + void store_values(List &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 === 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 &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 *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 *target_columns, - List *target_or_source_columns, - List *update_fields, - List *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 &list, SELECT_LEX_UNIT *u); - virtual int prepare2(void); - bool send_data(List &items); - virtual void store_values(List &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 &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 &list, SELECT_LEX_UNIT *u); - - int binlog_show_create_table(TABLE **tables, uint count); - void store_values(List &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).