Commit 54caf667 authored by unknown's avatar unknown

Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES

 VALUES() was considered a constant. This caused replacing 
 (or pre-calculating) it using uninitialized values before the actual
 execution takes place.
 Mark it as a non-constant (still not dependent of tables) to prevent
 the pre-calculation.


mysql-test/r/insert_update.result:
  Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES
   - test case.
   - EXPLAIN output changed due to VALUES() not being considered a constant 
     anymore
mysql-test/t/insert_update.test:
  Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES
   - test case.
sql/item.h:
  Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES
   - mark Item_insert_value as non-constant to prevent early calculation.
parent b527a75e
...@@ -63,9 +63,9 @@ Warnings: ...@@ -63,9 +63,9 @@ Warnings:
Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c`,values(test.t1.a) AS `VALUES(a)` from test.t1 Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c`,values(test.t1.a) AS `VALUES(a)` from test.t1
explain extended select * from t1 where values(a); explain extended select * from t1 where values(a);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
Warnings: Warnings:
Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c` from test.t1 Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c` from test.t1 where values(test.t1.a)
DROP TABLE t1; DROP TABLE t1;
create table t1(a int primary key, b int); create table t1(a int primary key, b int);
insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5); insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5);
...@@ -197,3 +197,25 @@ PRIMARY KEY (a) ...@@ -197,3 +197,25 @@ PRIMARY KEY (a)
) ENGINE=MyISAM; ) ENGINE=MyISAM;
INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ; INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1
(
a BIGINT UNSIGNED,
b BIGINT UNSIGNED,
PRIMARY KEY (a)
);
INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
SELECT * FROM t1;
a b
45 1
INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b =
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
SELECT * FROM t1;
a b
45 2
INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
SELECT * FROM t1;
a b
45 2
DROP TABLE t1;
...@@ -115,4 +115,27 @@ INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ; ...@@ -115,4 +115,27 @@ INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES
#
# End of 4.1 tests # End of 4.1 tests
CREATE TABLE t1
(
a BIGINT UNSIGNED,
b BIGINT UNSIGNED,
PRIMARY KEY (a)
);
INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
SELECT * FROM t1;
INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b =
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
SELECT * FROM t1;
INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
IF(VALUES(b) > t1.b, VALUES(b), t1.b);
SELECT * FROM t1;
DROP TABLE t1;
...@@ -1241,7 +1241,11 @@ class Item_insert_value : public Item_field ...@@ -1241,7 +1241,11 @@ class Item_insert_value : public Item_field
{ {
return Item_field::save_in_field(field_arg, no_conversions); return Item_field::save_in_field(field_arg, no_conversions);
} }
table_map used_tables() const { return (table_map)0L; } /*
We use RAND_TABLE_BIT to prevent Item_insert_value from
being treated as a constant and precalculated before execution
*/
table_map used_tables() const { return RAND_TABLE_BIT; }
bool walk(Item_processor processor, byte *args) bool walk(Item_processor processor, byte *args)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment