Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix truncate on MySQL >= 5.5 #549

Closed
wants to merge 1 commit into from

Conversation

ddeboer
Copy link

@ddeboer ddeboer commented Mar 22, 2014

When truncating tables on MySQL >= 5.5, an error is thrown:

SQLSTATE[42000]: Syntax error or access violation: 
1701 Cannot truncate a table referenced in a foreign key constraint ...

It turns out that with MySQL 5.5.7, TRUNCATE behaviour has changed. From the MySQL docs:

TRUNCATE TABLE fails for an InnoDB table if there are any FOREIGN KEY constraints from other tables that reference the table. Foreign key constraints between columns of the same table are permitted.

This PR disables foreign key checks just before, and re-enables them just after, truncate.

As I encountered this issue using doctrine/data-fixtures, I originally submitted a fix there: doctrine/data-fixtures#127. However, as @deeky666 pointed out, the DBAL is a better place for the fix.

@doctrinebot
Copy link

Hello,

thank you for creating this pull request. I have automatically opened an issue
on our Jira Bug Tracker for you. See the issue link:

http://www.doctrine-project.org/jira/browse/DBAL-844

We use Jira to track the state of pull requests and the versions they got
included in.

@Ocramius
Copy link
Member

@ddeboer this could need a test, as well as a small functional test that could be useful to identify whether the behavior changes in MySQL and if people installing the DBAL actually can change these settings (running the test suite can reveal incompatibilities).

I don't like this, but I guess MySQL can't be helped :(

@tPl0ch
Copy link

tPl0ch commented Mar 23, 2014

@Ocramius How about using some kind of VersionGuesser which does either a SELECT @@version or SELECT VERSION()

@deeky666
Copy link
Member

@tPl0ch platform version constraints are done through subclassing the base platform. See PostgreSQL, SQL Server and SQL Anywhere platforms. Even MySQL has a MySQL57Platform already. There also is a new feature in DBAL 2.5 automatically choosing the correct platform in the connection. See #487

@deeky666
Copy link
Member

@ddeboer I'm not sure whether we should add this behaviour for MySQL 5.5.7 and onwards only and avoid disabling foreign key checks by default for lower versions. Also I still find it rather dangerous just disabling the integrity checks by default. I would like to have a more explicit possiblity to get this behaviour so that the "normal" TRUNCATE stays safe.
I will think about it once again. Sorry for being so picky here but should be careful about that in this place :(

@ddeboer
Copy link
Author

ddeboer commented Mar 23, 2014

@Ocramius I’ll come up with a test once we’ve agreed on where and how to add this fix.

@deeky666 Are you suggesting to move the getTruncateTableSQL method to the MySQL57Platform class? I guess that would make sense. By the way, the fix could be limited to InnoDB (as the behaviour only occurs on that engine), but I saw no way in the DBAL of determining the database engine.

Another option would be to replace truncate with a delete and resetting the auto-increment. That way, we wouldn’t have to disable foreign key checks.

@ddeboer
Copy link
Author

ddeboer commented Mar 23, 2014

@tPl0ch Interesting solution. But by requiring a user parameter (disable_fk_checks) to be set, truncate doesn’t work out of the box on MySQL > 5.5.7. Perhaps we could assume true for the parameter if it’s not set, and allow users to specify false if they don’t want this behaviour?

@tPl0ch
Copy link

tPl0ch commented Mar 23, 2014

@ddeboer Hmm, assuming true would change the current behavior. Userland code most probably has already applied a variety of fixes for this issue which could break.

@deeky666
Copy link
Member

deeky666 commented Feb 7, 2017

Closing here. For an explanation to why we won't / can't do anything in DBAL please see: #2620

@deeky666 deeky666 closed this Feb 7, 2017
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants