Bug #47132 | CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables | ||
---|---|---|---|
Submitted: | 4 Sep 2009 12:08 | Modified: | 9 Sep 2010 17:44 |
Reporter: | Satya B | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server | Severity: | S3 (Non-critical) |
Version: | 5.0, 5.1+ | OS: | Any |
Assigned to: | Libing Song | CPU Architecture: | Any |
Tags: | CREATE TABLE, create view, if not exists |
[4 Sep 2009 12:08]
Satya B
[4 Sep 2009 12:46]
Peter Laursen
It is even worse for me on 5.1.38 (Windows7 64 bit, 64 bit server). USE satya; CREATE TABLE t1(a INT); CREATE TABLE t2(b INT); CREATE TABLE t3(c INT); INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t2 VALUES (4),(5),(6); INSERT INTO t3 VALUES (7),(8),(9); CREATE VIEW v1 AS SELECT * FROM t1,t2; CREATE VIEW v2 AS SELECT * FROM t1; CREATE TABLE IF NOT EXISTS v1(a INT, b INT) SELECT * FROM t3; -- server crashed!! -- after starting server we continue CREATE TABLE IF NOT EXISTS v2(a INT) SELECT * FROM t3; -- (3 row(s) affected, 1 warning(s)) SHOW WARNINGS; -- Table 'v2' already exists SHOW FULL TABLES; /* Tables_in_satya Table_type --------------- ---------- t1 BASE TABLE t2 BASE TABLE t3 BASE TABLE v1 VIEW v2 VIEW */ SELECT * FROM v2; /* a ------ 1 2 3 7 8 9 */ so conclusions.. 1) this is an 'S1' bug due to the crash 2) the succesfull statement should not insert anything - not even do anything. As long as tables and views in a MySQL database cannot be named the same the statement should return 'table already exists',
[4 Sep 2009 13:26]
MySQL Verification Team
c:\dbs>c:\dbs\5.0\bin\mysql -uroot --port=3500 --prompt="mysql 5.0 > " Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.85-Win X64 Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql 5.0 > create database gg; Query OK, 1 row affected (0.00 sec) mysql 5.0 > use gg Database changed mysql 5.0 > CREATE TABLE t1(a INT); Query OK, 0 rows affected (0.25 sec) mysql 5.0 > CREATE TABLE t2(b INT); Query OK, 0 rows affected (0.14 sec) mysql 5.0 > CREATE TABLE t3(c INT); Query OK, 0 rows affected (0.13 sec) mysql 5.0 > mysql 5.0 > INSERT INTO t1 VALUES (1),(2),(3); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql 5.0 > INSERT INTO t2 VALUES (4),(5),(6); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql 5.0 > INSERT INTO t3 VALUES (7),(8),(9); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql 5.0 > mysql 5.0 > CREATE VIEW v1 AS SELECT * FROM t1,t2; Query OK, 0 rows affected (0.11 sec) mysql 5.0 > CREATE VIEW v2 AS SELECT * FROM t1; Query OK, 0 rows affected (0.09 sec) mysql 5.0 > mysql 5.0 > CREATE TABLE IF NOT EXISTS v1(a INT, b INT) SELECT * FROM t3; ERROR 2013 (HY000): Lost connection to MySQL server during query mysql 5.0 >
[4 Sep 2009 14:17]
MySQL Verification Team
Thank you for the bug report. On my side 5.0/5.1 both crashes and 5.4.4 has different results than you reported. Which server version had you tested. Thanks in advance.
[4 Sep 2009 15:47]
Peter Laursen
@Miguel Wasn't it more relistic to mark as 'verified' than 'need feedback'? After all you found two problems yourself: 1) a crash 2) insistent behavior across versions The problem is that only the original reporter can change status (by replying). If he does not, this report will expire with 'no feedback' classification. And then I will have to create a new bug report after 1 month (as I cannot change status of this one) and starting fixing the bug(s) will take 1 month than what it needs to! This has happened some times before. There is a crash in the two still-supported stable versions. So no matter what CREATE TABLE .. SELECT has problems if a VIEW exists named as the table specified in CREATE. By the way: don't you think it is bug too what I reported that the CREATE TABLE statement that succeeds INSERTS into existing VIEW? You did not comment on that. I can create one or two new bug reports of course if you want this one strictly focused on what Satya reported, but then Sveta will reply and scold me and tell that I should not report bugs that have already been reported! :-)
[5 Sep 2009 12:27]
Peter Laursen
For me there is no difference between 5.1.38 and 5.4.1. They both exhibit the behaviour: 1) crash on the statement "CREATE TABLE IF NOT EXISTS v1(a INT, b INT) SELECT * FROM t3;" 2) values (7,8,9) get INSERTED to t1 (and thus on v2 too) on the statement "CREATE TABLE IF NOT EXISTS v2(a INT) SELECT * FROM t3;" My personal opinion is that 2) is worse than 1) actually (but official guidelines here seems to be opposite: a server crash is panic - corruption of user's data not very important! :-( )
[5 Sep 2009 13:28]
Davi Arnaut
This bug is a spin off from Bug#46384 which addresses the crash and the bug is marked private for due to its seriousness but the patch is public. This bug focus on analyzing the specific problem reported by Satya, which spans over all versions of MySQL, while the crash only occurred on 5.0 and 5.1 -- the reason is that the code is quite different among the server versions. Please, don't open up any extra bug reports. This bug has been opened because we are already working on the related issues.
[5 Sep 2009 14:06]
Peter Laursen
"while the crash only occurred on 5.0 and 5.1" well .. 5.4.1 crashes for me too. But it may be fixed in 5.4 trunk of course. I have no problems waiting for conclusions in this and the other report mentioned.
[7 Sep 2009 5:15]
Satya B
My Bad, should have mentioned that the crash is fixed by BUG#46384 and this bug is a spin off. It wasn't crashing in 5.4 (verified in mysql-pe) branch, may be there are some fixes to be merged to main trunk.
[11 Sep 2009 8:52]
Martin Hansson
I think it's likely we can close this as not a bug, adding a line or two in the manual. First let us get some things straight: 1) This bug does not deal with the crash, since that bug (Bug#46384) is closed. 2) Hence, let us not consider what happened before that patch was pushed. 3) Rather, let us look at the strange new behaviour that results (slightly minimized test case, did away with t3) SELECT version(); version() 5.1.39-debug-log // Same behaviour in all versions, 5.0, 5.1, 5.4 CREATE TABLE t1(a INT); CREATE TABLE t2(b INT); INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t2 VALUES (4),(5),(6); CREATE VIEW v1 AS SELECT * FROM t1,t2; CREATE VIEW v2 AS SELECT * FROM t1; CREATE TABLE IF NOT EXISTS v1(a INT, b INT) SELECT 100 AS a, 200 AS b; ERROR 42S01: Table 'v1' already exists SELECT * FROM v1; a b 1 4 2 4 3 4 1 5 2 5 3 5 1 6 2 6 3 6 SHOW CREATE TABLE v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b` from (`t1` join `t2`) latin1 latin1_swedish_ci CREATE TABLE IF NOT EXISTS v2(a INT) SELECT 100 AS a; Warnings: Note 1050 Table 'v2' already exists SELECT * FROM v2; a 1 2 3 100 SHOW CREATE TABLE v2; View Create View character_set_client collation_connection v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`a` AS `a` from `t1` latin1 latin1_swedish_ci Strange indeed. Ostensibly, v2 is still view over t1. Yet it retains the value 100 from the new view definition. This has to come from somewhere! Now what about t1? SELECT * FROM t1; a 1 2 3 100 Yes indeed, it ended up in t1! Actually, this behaviour doesn't seem too far-fetched. Since according to the manual, CREATE TABLE IF NOT EXISTS is supposed to act more or less like an INSERT INTO ... SELECT ... if that table-to-be-created exists. One might have opinions on this (and personally I don't like it) but it is established and documented behaviour. And insertion into a single-table view will insert into its underlying table. However, insertion into a join view is forbidden, and rightfully so. Not completely intuitive, but it's logical if you think about it.
[11 Sep 2009 9:32]
Peter Laursen
I do not understand. I think you only complicate. Let me repeat: CREATE TABLE IF NOT EXISTS v2(a INT) SELECT * FROM t3; -- (3 row(s) affected, 1 warning(s)) SHOW WARNINGS; -- Table 'v2' already exists If table exists then CREATE TABLE IF NOT EXISTS should return a error simply. What else does IF NOT EXISTS mean? "CREATE TABLE IF NOT EXISTS" and the warning "table already exists" are inconsistent. Also nobody has a change to foresee that values (7,8,9) get INSERTED: SELECT * FROM v2; /* a ------ 1 2 3 7 8 9 */ Is it more important to close reports than to fix bugs?
[12 Sep 2009 3:03]
Davi Arnaut
"IF NOT EXISTS" was explicitly designed to not emit a error if the object exists. This is documented behavior. Also, your testy comments are uncalled for. Please, let's keep a civic tone and solely based on technical arguments.
[12 Sep 2009 7:44]
Peter Laursen
The core of the discussion is this: CREATE TABLE one_table ...; ..results in.. INSERT INTO another_table ...; ..what is nonsense to me. For this discussion *technical arguments* are not required at all - *common sense arguments* are enough. No documentation can change that. In this particular situation CREATE TABLE should raise an error - not a warning - and nothing should happen at all. It does not matter if my comments were 'called for'. Guidelines here are that 'anyone can comment on a bug'. But you can disclose that other bug report, so that we can see the complete discussion about this. That wold be the best way to ensure proper communication!
[12 Sep 2009 12:33]
Davi Arnaut
> The core of the discussion is this: > > CREATE TABLE one_table ...; > ..results in.. > INSERT INTO another_table ...; No. It has to be a CREATE TABLE IF NOT EXISTS. On the other hand, CREATE TABLE does raise a error. I invite you to read the documentation for "IF NOT EXISTS": "The keywords IF NOT EXISTS prevent an error from occurring if the table exists. However, there is no verification that the existing table has a structure identical to that indicated by the CREATE TABLE statement." and "For CREATE TABLE ... SELECT, if IF NOT EXISTS is given and the table already exists, MySQL handles the statement as follows" .. Which details how it behaves and that the rows are inserted only if the "IF NOT EXISTS" keywords are supplied and the table exists. BTW, this is very similar to how other databases implement the "IF NOT EXISTS" keywords. Now, this behavior might not make sense to you but it has been this way for several years and there are lot of applications and users that expect this behavior. In my personal opinion, this doesn't make much sense either, but opinions are not compelling arguments to change something that has be relied upon for years. On top, our guidelines don't allow us to change this in stable releases. In this case, what is documented prevails. What is (hopefully) being discussed here is that the documented behavior does not apply if the underlying object is a multiple table view. > It does not matter if my comments were 'called for'. Guidelines here are that > 'anyone can comment on a bug'. Sure, but comments like "Is it more important to close reports than to fix bugs?" (the testy comment) adds nothing to the discussion and can only alienate people from having a technical discussion with you. I'm not asking for no discussion, I'm asking for a respectful discussion.
[12 Sep 2009 13:47]
Peter Laursen
" I invite you .." .. so now it is me who will have to ask for a civic tone here. No matter if IF EXISTS is used or not, CREATE TABLE should not do anything with any other table than the one specified as parameter for CREATE TABLE.
[12 Sep 2009 13:52]
Davi Arnaut
> " I invite you .." .. so now it is me who will have to ask for a civic tone here. OK. > No matter if IF EXISTS is used or not, CREATE TABLE should not do anything > with any other table than the one specified as parameter for CREATE TABLE. I agree.
[12 Sep 2009 13:57]
Peter Laursen
Additionally I wrote this "Is it more important to close reports than to fix bugs?" as a reply to Martin who wrote "I think it's likely we can close this as not a bug, adding a line or two in the manual." "adding a line or two in the manual" changes nothing. I also do not believe users will expect this behavior as you claim. On the opposite I think it would surprise everybody who knew.
[12 Sep 2009 14:18]
Davi Arnaut
> I also do not believe users will expect this behavior as you claim. On the opposite > I think it would surprise everybody who knew. But it would certainly break various applications. For example, phpMyAdmin uses "IF NOT EXISTS" where it intends the statement to be a no-op if the table exists -- there are certainly other applications relying on the documented behavior. If the user expects a error, do not use "IF NOT EXISTS". Now, I agree with you that the implicit INSERT behavior is indeed counter intuitive, but... it is what it is and seems to have been designed and documented this way. We can't change it now without causing even more confusion (and incompatible changes by consequence). Backwards compatibility is important. What we propose for now is to expand the documentation (in 5.0 and up) to clarify this behavior, especially with regard to views.
[12 Sep 2009 14:44]
Peter Laursen
I do not believe any application - also not PMA - expects the behavior that data are INSERTED on a CREATE TABLE [IF NOT EXISTS] statement. But OK .. an error may cause application failures (like terminating completion of a script) if it is unexpected. My main concern is and was the INSERTS, that may corrupt table data for users should they accidentally specify a colliding table name. This is actually serious in my opinion. Equally or more serious than the server crash according to my priorities (but not to official criteria here, I think). In my logic CREATE TABLE [IF NOT EXISTS] should mean: [IF NOT EXISTS]: CREATE TABLE [IF EXISTS]: do nothing (because no action was specified for the condition). Actually and with hindsight there is no error and should not be if nothing is done. So warning is consistent. I admit to have been mistaken here. I think we have made clear our positions now and I can only repeat what I have said already. So I will probably not write here again. btw: the argumentation that it is implemented and documented like does not seem valid to me. Then there was no reason to fix bugs - you could simply always update documentation instead! So fire all developers and hire 50 documentationists :-)
[12 Sep 2009 17:29]
Peter Laursen
"Another testy comment that only downgrades the level of the discussion" .. my point was that *because it is implemented and documented like that* is not always a valid criteria for deciding on bug/not a bug. If it was you would be able to document any buggy behavior and call it 'not a bug' and my comment would be valid. Now you refer to another criteria named 'intended behavior'. Maybe the person who coded this *intended* it - but I rather think he *overlooked* it. Who ultimately decides what is *intended behavior* here? Anyway: will it be considered *a bug* or *intended behavior* that "CREATE TABLE ... some_table ..." does "INSERT INTO ... some_other_table ..." in specific scenarios? Could you please reply to that unambigously. Because that reply I am still missing.
[12 Sep 2009 19:41]
Davi Arnaut
> "Another testy comment that only downgrades the level of the discussion" .. my > point was that *because it is implemented and documented like that* is not always > a valid criteria for deciding on bug/not a bug. If it was you would be able to > document any buggy behavior and call it 'not a bug' and my comment would be valid. Agree. > Now you refer to another criteria named 'intended behavior'. Maybe the person who > coded this *intended* it - but I rather think he *overlooked* it. Exactly, and this where we disagree. > Who ultimately decides what is *intended behavior* here? Not me. In this case, probably a senior developer that was around back when this was introduced. > Anyway: will it be considered *a bug* or *intended behavior* that "CREATE TABLE ... > some_table ..." does "INSERT INTO ... some_other_table ..." in specific scenarios? > Could you please reply to that unambigously. Because that reply I am still missing. I personally think it is intended behavior as it has been this way for about 10 years -- there are even test cases to ensure this behavior. The code itself predates the use of revision control for the source code, so i can't find the exact changeset that introduced this.
[12 Sep 2009 19:53]
Peter Laursen
"it is intended behavior as it has been this way for about 10 years" .. but then later introduction of VIEWS also introduced some non-intended behavior I think? VIEWS have not been there for 10 years, but 4-5 years only. The issue occurs due to naming collision with a VIEW, doesn't it? So the remaining issue for me can be described like this: "CREATE TABLE tablename IF NOT EXISTS .." may generate INSERTS to an unreferenced table if 'tablename' collides with the name of an existing VIEW. (If not I will have to replay the test case all over again to refresh my memory!).
[15 Sep 2009 13:38]
Davi Arnaut
> The issue occurs due to naming collision with a VIEW, doesn't it? Yes, somewhat. Views and tables share the same namespace. > So the remaining issue for me can be described like this: > > "CREATE TABLE tablename IF NOT EXISTS .." may generate INSERTS to an unreferenced > table if 'tablename' collides with the name of an existing VIEW. Somewhat, yes. The bug and discrepancy is that if the object referenced in the CREATE TABLE exists and is a view, the data is inserted. If the object is a multiple table view, no data is inserted. We need to determine what is the intended behavior with respect to if the object is a view (*). Once this is done, we can determine whether there is a bug to fix or documentation to improve. * Both the IF NOT EXISTS for a CREATE TABLE and the implicit insert.
[15 Sep 2009 14:20]
Georgi Kodinov
I agree with Peter that this is counter-intuitive. I would have expected that CREATE TABLE IF NOT EXISTS does all (if there's no table) or nothing (if the table exists), i.e the correct operation should be : if (<table> not exists) { CREATE TABLE; INSERT ...; } and not : if (<table> not exists) { CREATE TABLE; } INSERT ... However this second behavior is what has been implemented (a long time ago) and documented (a long time ago). And thus it became the behavior that people expect. And I hope you will understand that we can't just go and change it in a release version bugfix : it will have the potential to break a good deal of not-very-intuitive-but-following-mysql-docs apps. Instead we should consider this as a feature completion fix for the development branch.
[15 Sep 2009 15:09]
Peter Laursen
why not (as a 1st step workaround) add the condition if (<table> is not VIEW) { INSERT ... } .. but maybe that is not easy-to-go-with as I understand Davi's remark about shared space for tables and views. I cannot accept data corruption as a result of valid and unreleated statements. I also find it disappointing that I had to be nasty to get attention to this (my nastiness was a 'tactical nastiness' :-) ) However I can accept of course that priority will have to be decided according to what other bugs and tasks are pending and the relative importance of those. (*to be fixed later* + documenting) is acceptable if it is absolutely required complications and current workload taken into consideration. *not a bug* is not acceptable in my opinion simply because CREATE should not INSERT (except for CREATE .. SELECT .. of course).
[16 Sep 2009 8:20]
Georgi Kodinov
I hope you would agree that replacing 1 non-intuitive solution (the current one) with another is not a good idea. And it's not about technical arguments or ease of implementation. It is about keeping consistent behavior in a GA release.
[16 Sep 2009 8:34]
Peter Laursen
I think the conclusion is that we are not able to understand another Look at this (because this is the only test case required for the discussion in my opinion): SELECT * FROM t1; /* a ------ 1 2 3 */ CREATE TABLE IF NOT EXISTS v2(a INT) SELECT * FROM t3; -- (3 row(s) affected, 1 warning(s)) SELECT * FROM t1; /* a ------ 1 2 3 7 8 9 */ This is data corruption simply I my opinion. In my priority this as far more important than any consideration about consistent behavior. Maybe you think that I am nasty again, but if 'consistent behavior' was so important then bugs should never be fixed! Every bugfix breaks 'consistency' in some sense. If VIEWS did not exist there was no problem (pardon if I miss some detail). But introduction of VIEWS created this with CREATE TABLE IF NOT EXISTS. However it can very well happen that user specifies a table name that collides with the name of a VIEW.
[16 Sep 2009 12:13]
Georgi Kodinov
Let's not turn the bug report into a discussion board please. Feel free to contact me on my e-mail (joro at sun dot com).
[16 Sep 2009 12:33]
Peter Laursen
I was replying to questions "I hope you understand ..". If the questions had not appeared I would not have posted the last 2 or 3 times. If you do not like the answer then you should not ask the question. I refuse to make it a private discussion as it affects not only you and me. But I have no plans to post again here as I think I have made my position clear. It is data corruption and this is for me the worst possible kind of a bug. I think it should be a 'verified' bug (but priorities will have to decide if the fix should go into 5.0/5.1 or only from 5.4 or later).
[16 Sep 2009 18:51]
Davi Arnaut
Just for the record: the internals mailing list (http://lists.mysql.com/internals/) is a attractive alternative for technical discussions like this.
[16 Sep 2009 20:16]
Peter Laursen
I do not find it is a technical discussion and I have no intentions to get involved in MySQL internals at all. I have started my own discussion here (so that you will not be bothered by more from me here): http://www.webyog.com/blog/2009/09/16/bug-or-not-a-bug-part-1/
[4 Nov 2009 19:26]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/89358 2939 Alexey Botchkov 2009-11-04 Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables if the created table already exists, we insert no rows in the existing tables. In the binary log we write CREATE TABLE command with the structure of the existing table. Several tests have to be fixed then as CREATE TABLE IF EXISTS SELECT statements are replaced with the INSERT INTO SELECT per-file comments: mysql-test/r/auto_increment.result Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables result updated mysql-test/r/create.result Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables result updated mysql-test/r/trigger.result Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables result updated mysql-test/t/auto_increment.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables test fixed. mysql-test/t/create.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables test fixed. mysql-test/t/trigger.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables test fixed. sql/sql_insert.cc Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables do nothing if the table already exists.
[5 Nov 2009 16:08]
Georgi Kodinov
Alexey, You should make the entire statement fails, e.g. : #setup CREATE TABLE t0 (a int); CREATE TABLE t1 (a int); # this should fail with an error CREATE TABLE t1(a INT) SELECT * FROM t0; # just like this will fail with an error CREATE TABLE t1(a INT); # this shouldn't insert any rows : CREATE TABLE IF NOT EXISTS t1(a INT) SELECT * FROM t0; # just like this one : CREATE TABLE IF NOT EXISTS t1(a INT); Please also add a more elaborate test case.
[17 Nov 2009 13:51]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/90667 2952 Alexey Botchkov 2009-11-16 Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables if the created table already exists, we insert no rows in the existing tables. In the binary log we write CREATE TABLE command with the structure of the existing table. Several tests have to be fixed then as CREATE TABLE IF EXISTS SELECT statements are replaced with the INSERT INTO SELECT per-file comments: mysql-test/r/auto_increment.result Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables result updated mysql-test/r/create.result Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables result updated mysql-test/r/trigger.result Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables result updated mysql-test/t/auto_increment.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables test fixed. mysql-test/t/create.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables Test case added, and the rest of the test fixed. mysql-test/t/trigger.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables test fixed. sql/sql_insert.cc Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables do nothing if the table already exists.
[24 Nov 2009 13:38]
Konstantin Osipov
Bug#46153 was closed as "Not a Bug", it's a duplicate of this bug.
[25 Nov 2009 8:57]
Zhenxing He
First I want to claim that I'm OK with the idea to not insert data if the object already exist, but I have some concerns on the proposed patch. After the patch, a CREATE TABLE IF NOT EXISTS...SELECT will be binlogged as a CREATE TABLE statement if the object already exists even if **statement format** is used, which I think is not good, I think we should binlog the statement as is when statement format is used. CREATE TABLE IF NOT EXISTS or CREATE TABLE IF NOT EXISTS LIKE statements are binlogged as is whether the object exists or not in statement format, if we want to change the behavior, then the behavior of these two statement should also be change to make them consistent. I think that the current binlogging behavior for statement format should not be changed.
[5 Feb 2010 12:01]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/99399 2952 Alexey Botchkov 2010-02-04 Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables The decision was made to simplify the CREATE TABLE IF NOT EXISTS. It is not going to do anything if the table already exists. (Before it tried to insert the SELECT result into the existing table). Several tests have to be fixed then as CREATE TABLE IF EXISTS SELECT statements are replaced with the INSERT INTO SELECT per-file comments: mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables mysql-test/r/auto_increment.result result updated Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables mysql-test/r/create.result result updated Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables mysql-test/r/trigger.result result updated Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables mysql-test/t/auto_increment.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables mysql-test/t/create.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables mysql-test/t/trigger.test Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables sql/sql_insert.cc Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables Do no insert if the table already exists. Binlog the statement as it is for the statement format.
[17 Feb 2010 13:00]
Luis Soares
If I understood it correctly, won't this make master and slave go out of sync when statement based replication is used? For instance (consider O - old, N - new, M - master, S - slave): - OM --> NS MASTER> CREATE TABLE t0 (a INT); MASTER> CREATE TABLE t1 (a INT); MASTER> INSERT INTO t0 (1),(2),(3); MASTER> CREATE TABLE IF NOT EXISTS t1 SELECT * FROM t0 MASTER> SELECT * FROM t1; {1,2,3} -- sync_slave_with_master SLAVE> SELECT * FROM t1; {} - NM --> OS MASTER> CREATE TABLE t0 (a INT); MASTER> CREATE TABLE t1 (a INT); MASTER> INSERT INTO t0 (1),(2),(3); MASTER> CREATE TABLE IF NOT EXISTS t1 SELECT * FROM t0 MASTER> SELECT * FROM t1; {} -- sync_slave_with_master SLAVE> SELECT * FROM t1; {1,2,3}
[17 Feb 2010 13:03]
Luis Soares
To make my previous comment clear, I am considering: 1. cross-version replication; 2. statement based replication; 3. Old server does not contain the proposed fix, whereas New server does. Regards, Luís
[26 Mar 2010 2:56]
Zhenxing He
See also bug#51501, which can also be fixed by the proposed solution for this bug (i.e. not executing the insert part when the table already exists).
[5 Jul 2010 10:47]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/112878 3078 Li-Bing.Song@sun.com 2010-07-05 Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables The decision was made to simplify the CREATE TABLE IF NOT EXISTS. It is not going to do anything if the table already exists. (Before it tried to insert the SELECT result into the existing table). Several tests have to be fixed then as CREATE TABLE IF EXISTS SELECT statements are replaced with the INSERT INTO SELECT @ mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test Nothing inserts into the table when it exists. So error ER_DUP_ENTRY will not happen. @ mysql-test/include/mix1.inc Nothing inserts into the table when it exists. So error ER_DUP_ENTRY will not happen. @ mysql-test/suite/rpl/t/rpl_create_if_not_exists.test Verify 'CREATE TABLE IF NOT EXISTS ... SELECT' statements are not binlogged if the table exists. @ mysql-test/t/auto_increment.test Nothing inserts into the table when it exists. So use 'INSERT ... SELECT' instead of 'CREATE ...SELECT'. @ mysql-test/t/create.test Nothing inserts into the table when it exists. So use 'INSERT ... SELECT' instead of 'CREATE ...SELECT'. Add test to verify that nothing will insert into the table if it exists. @ mysql-test/t/trigger.test Nothing inserts into the table when it exists. So use 'INSERT ... SELECT' instead of 'CREATE ...SELECT'.
[5 Jul 2010 20:34]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/112918 3076 Konstantin Osipov 2010-07-06 A fix for Bug#47132 (with review comments).
[6 Jul 2010 3:20]
Libing Song
In order to keep consistency between New master and Old slave, the statement will not be binlogged if the table exists.
[6 Jul 2010 8:34]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/112931 3076 Li-Bing.Song@sun.com 2010-07-06 Bug#47132 CREATE TABLE.. SELECT.. data not inserted if table is view over multiple tables The decision was made to simplify the CREATE TABLE IF NOT EXISTS. It is not going to do anything if the table already exists. (Before it tried to insert the SELECT result into the existing table). In order to keep consisteny between New master and Old slave, the statement will not be binlogged if the table already exists. Several tests have to be fixed then as CREATE TABLE IF EXISTS SELECT statements are replaced with the INSERT INTO SELECT
[18 Aug 2010 9:26]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/116060 3184 Li-Bing.Song@sun.com 2010-08-18 WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT EXISTS ... SELECT' behaviour BUG#47132, BUG#47442, BUG49494, BUG#23992 and BUG#48814 will disappear automatically after the this patch. BUG#55617 is fixed by this patch too. This is the 5.5 part. It implements: - 'CREATE TABLE IF NOT EXISTS ... SELECT' statement will not insert anything and binlog anything if the table already exists. It only generate a warning that table already exists. - A couple of test cases for the behavior changing.
[18 Aug 2010 9:38]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/116062 3186 Li-Bing.Song@sun.com 2010-08-18 WL#5370 Keep forward-compatibility when changing 'CREATE TABLE IF NOT EXISTS ... SELECT' behaviour BUG#47132, BUG#47442, BUG49494, BUG#23992 and BUG#48814 will disappear automatically after the this patch. BUG#55617 is fixed by this patch too. This is the 5.5 part. It implements: - 'CREATE TABLE IF NOT EXISTS ... SELECT' statement will not insert anything and binlog anything if the table already exists. It only generate a warning that table already exists. - A couple of test cases for the behavior changing.
[19 Aug 2010 7:47]
Libing Song
It disappears after the patch for WL#5370. As behavior of CREATE TABLE IF NOT EXISTS SELECT has changed. It will never insert anything and not be binlogged after the worklog.
[25 Aug 2010 9:23]
Bugs System
Pushed into mysql-5.5 5.5.6-m3 (revid:alik@ibmvm-20100825092002-2yvkb3iwu43ycpnm) (version source revid:alik@ibmvm-20100825092002-2yvkb3iwu43ycpnm) (merge vers: 5.5.6-m3) (pib:20)
[30 Aug 2010 8:31]
Bugs System
Pushed into mysql-trunk 5.6.1-m4 (revid:alik@sun.com-20100830082732-n2eyijnv86exc5ci) (version source revid:alik@sun.com-20100830082732-n2eyijnv86exc5ci) (merge vers: 5.6.1-m4) (pib:21)
[30 Aug 2010 8:35]
Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100830082745-n6sh01wlwh3itasv) (version source revid:alik@sun.com-20100830082745-n6sh01wlwh3itasv) (pib:21)
[9 Sep 2010 17:44]
Paul DuBois
Noted in 5.1.51, 5.5.6, 5.6.1 changelogs. As of MySQL 5.5.6, handling of CREATE TABLE IF NOT EXISTS ... SELECT statements has been changed for the case that the destination table already exists: * Previously, for CREATE TABLE IF NOT EXISTS ... SELECT, MySQL produced a warning that the table exists, but inserted the rows and wrote the statement to the binary log anyway. By contrast, CREATE TABLE ... SELECT (without IF NOT EXISTS) failed with an error, but MySQL inserted no rows and did not write the statement to the binary log. * MySQL now handles both statements the same way when the destination table exists, in that neither statement inserts rows or is written to the binary log. The difference between them is that MySQL produces a warning when IF NOT EXISTS is present and an error when it is not. This change in handling of IF NOT EXISTS results in an incompatibility for statement-based replication from a MySQL 5.1 master with the original behavior and a MySQL 5.5 slave with the new behavior. Suppose that CREATE TABLE IF NOT EXISTS ... SELECT is executed on the master and the destination table exists. The result is that rows are inserted on the master but not on the slave. (Row-based replication does not have this problem.) To address this issue, statement-based binary logging for CREATE TABLE IF NOT EXISTS ... SELECT is changed in MySQL 5.1 as of 5.1.51: * If the destination table does not exist, there is no change: The statement is logged as is. * If the destination table does exist, the statement is logged as the equivalent pair of CREATE TABLE IF NOT EXISTS and INSERT ... SELECT statements. (If the SELECT in the original statement is preceded by IGNORE or REPLACE, the INSERT becomes INSERT IGNORE or REPLACE, respectively.) This change provides forward compatibility for statement-based replication from MySQL 5.1 to 5.5 because when the destination table exists, the rows will be inserted on both the master and slave. To take advantage of this compatibility measure, the 5.1 server must be at least 5.1.51 and the 5.5 server must be at least 5.5.6. To upgrade an existing 5.1-to-5.5 replication scenario, upgrade the master first to 5.1.51 or higher. Note that this differs from the usual replication upgrade advice of upgrading the slave first. A workaround for applications that wish to achieve the original effect (rows inserted regardless of whether the destination table exists) is to use CREATE TABLE IF NOT EXISTS and INSERT ... SELECT statements rather than CREATE TABLE IF NOT EXISTS ... SELECT statements. Along with the change just described, the following related change was made: Previously, if an existing updatable view was named as the destination table for CREATE TABLE IF NOT EXISTS ... SELECT, rows were inserted into the underlying base table and the statement was written to the binary log. As of MySQL 5.1.51 and 5.5.6, nothing is inserted or logged.