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 Nozdrin | 4 Oct |