yesodweb / yesodweb/persistent
Persistent generates invalid migration sql for MySQL when using 'default'
Nobody has claimed this yet.
- Dominant language
- Haskell
- Stars
- 486
- Forks
- 306
- PR merge metrics
- No merged PRs in 30d
Description
Hi all,
In an example scaffolded mysql Yesod project, my models file contains:
User
...
~createdat UTCTime default=current_timestamp
~updatedat UTCTime default=current_timestamp
I run:
stack exec -- yesod devel
...
Starting devel application
Migrating: ALTER TABLE `user` ADD COLUMN `createdat` DATETIME NOT NULL DEFAULT current_timestamp
22/Oct/2019:15:31:39 +0200 [Debug#SQL] ALTER TABLE `user` ADD COLUMN `createdat` DATETIME NOT NULL DEFAULT current_timestamp; []
Migrating: ALTER TABLE `user` ADD COLUMN `updatedat` DATETIME NOT NULL DEFAULT current_timestamp
...
Migrating: ALTER TABLE `user` ALTER COLUMN `createdat` SET DEFAULT current_timestamp
22/Oct/2019:15:31:41 +0200 [Debug#SQL] ALTER TABLE `user` ALTER COLUMN `createdat` SET DEFAULT current_timestamp; []
devel.hs: ConnectionError {errFunction = "query", errNumber = 1064, errMessage = "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'current_timestamp' at line 1"}
Unexpected: child process exited with ExitFailure 1
Trying again
...
The invalid SQL that is generated being:
ALTER TABLE `user` ALTER COLUMN `createdat` SET DEFAULT current_timestamp
Which seems to give the same MySQL error when I run it by pasting on the mysql command line client directly. I think the correct syntax should be:
ALTER TABLE user CHANGE `createdat` `createdat` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
This runs without error directly on the mysql client.
I notice that the first migrations that add the columns (including with the default) works (It's there when I run describe user directly), and that this additional ALTER migration isn't needed. The project will not run because of it.
I also tried with default=NOW() inside the models file, instead of current_timestamp, and also with double quotes like "default=current_timestamp" just to be certain, but the result is no different.
I will have to keep an auxiliary file of SQL commands to set MySQL triggers, to be run, as a work-around in the mean time.
Is this a bug, or am I using Persistent wrong?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the scaffolded models file and the SQL emitted by stack exec -- yesod devel, comparing the working ADD COLUMN statements with the failing ALTER statement. Inspect Persistent's MySQL migration generation for default changes; done means the reproduced migration runs successfully without invalid or unnecessary SQL.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- haskell, mysql
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100