diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 7c467749ee6..a351f02d655 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2980,4 +2980,38 @@ UPDATE v1 SET val=6 WHERE id=2; ERROR HY000: CHECK OPTION failed 'test.v1' DROP VIEW v1; DROP TABLE t1; +DROP VIEW IF EXISTS v1, v2; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY, j INT); +CREATE VIEW v1 AS SELECT j FROM t1; +CREATE VIEW v2 AS SELECT * FROM t1; +INSERT INTO t1 (j) VALUES (1); +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +1 +INSERT INTO v1 (j) VALUES (2); +# LAST_INSERT_ID() should not change. +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +1 +INSERT INTO v2 (j) VALUES (3); +# LAST_INSERT_ID() should be updated. +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +3 +INSERT INTO v1 (j) SELECT j FROM t1; +# LAST_INSERT_ID() should not change. +SELECT LAST_INSERT_ID(); +LAST_INSERT_ID() +3 +SELECT * FROM t1; +i j +1 1 +2 2 +3 3 +4 1 +5 2 +6 3 +DROP VIEW v1, v2; +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 2446bedfc14..62f01388f30 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2923,4 +2923,43 @@ UPDATE v1 SET val=6 WHERE id=2; DROP VIEW v1; DROP TABLE t1; + +# +# BUG#22584: last_insert_id not updated after inserting a record +# through a updatable view +# +# We still do not update LAST_INSERT_ID if AUTO_INCREMENT column is +# not accessible through a view. However, we do not reset the value +# of LAST_INSERT_ID, but keep it unchanged. +# +--disable_warnings +DROP VIEW IF EXISTS v1, v2; +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (i INT AUTO_INCREMENT PRIMARY KEY, j INT); +CREATE VIEW v1 AS SELECT j FROM t1; +CREATE VIEW v2 AS SELECT * FROM t1; + +INSERT INTO t1 (j) VALUES (1); +SELECT LAST_INSERT_ID(); + +INSERT INTO v1 (j) VALUES (2); +--echo # LAST_INSERT_ID() should not change. +SELECT LAST_INSERT_ID(); + +INSERT INTO v2 (j) VALUES (3); +--echo # LAST_INSERT_ID() should be updated. +SELECT LAST_INSERT_ID(); + +INSERT INTO v1 (j) SELECT j FROM t1; +--echo # LAST_INSERT_ID() should not change. +SELECT LAST_INSERT_ID(); + +SELECT * FROM t1; + +DROP VIEW v1, v2; +DROP TABLE t1; + + --echo End of 5.0 tests. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 09bf1737e39..0dd9823ffe3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3394,9 +3394,17 @@ end_with_restore_list: res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values, lex->update_list, lex->value_list, lex->duplicates, lex->ignore); - /* do not show last insert ID if VIEW does not have auto_inc */ + + /* + If we have inserted into a VIEW, and the base table has + AUTO_INCREMENT column, but this column is not accessible through + a view, then we should restore LAST_INSERT_ID to the value it + had before the statement. + */ if (first_table->view && !first_table->contain_auto_increment) - thd->first_successful_insert_id_in_cur_stmt= 0; + thd->first_successful_insert_id_in_cur_stmt= + thd->first_successful_insert_id_in_prev_stmt; + break; } case SQLCOM_REPLACE_SELECT: @@ -3456,9 +3464,17 @@ end_with_restore_list: /* revert changes for SP */ select_lex->table_list.first= (byte*) first_table; } - /* do not show last insert ID if VIEW does not have auto_inc */ + + /* + If we have inserted into a VIEW, and the base table has + AUTO_INCREMENT column, but this column is not accessible through + a view, then we should restore LAST_INSERT_ID to the value it + had before the statement. + */ if (first_table->view && !first_table->contain_auto_increment) - thd->first_successful_insert_id_in_cur_stmt= 0; + thd->first_successful_insert_id_in_cur_stmt= + thd->first_successful_insert_id_in_prev_stmt; + break; } case SQLCOM_TRUNCATE: