MySQL: Add ANSI_QUOTES support to MigrationsTableExists() #475
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR addresses #444
Problem
Dbmate currently fails to function against MySQL instances enabled with the ANSI_QUOTES sql_mode.
My initial investigation report can be found here.
Why
The ANSI_QUOTES mode does not allow double-quote characters to be used for expressing string literals. Therefore ANSI_QUOTES-enabled MySQL rejects the following query produced by Dbmate's MySQL driver:
From: https://github.com/amacneil/dbmate/blob/6245b8c/pkg/driver/mysql/mysql.go#L236
Fix & Thought Process
MySQL driver's quotedMigrationsTableName() complies with ANSI_QUOTES. Therefore I initially attempted to replicate other command implementations over to MigrationsTableExists() like so:
This would be ideal for two reasons:
However the query produced by the above code was considered invalid by MySQL (with and without ANSI_QUOTES). It appears that the LIKE predicate is picky about how the condition is quoted. Fair enough, I went a step further and tried this code instead:
Unfortunately, this time, the sql package's string interpolation was negatively affected. It seems to not appreciate the quotes around the
?
interpolation character.At this point I understood the agony of the person who last worked on this part of the code, and why MySQL driver's
MigrationsTableExists()
has an inconsistentfmt.Sprintf
based implementation. One code consistency I was able to pick up was lower-casing the entire query.The final code change may appear lazy but in fact a lot of thought went into it. Cheers!