yamoyamoto opened a new issue, #8744: URL: https://github.com/apache/incubator-devlake/issues/8744
### Search before asking - [x] I had searched in the [issues](https://github.com/apache/incubator-devlake/issues?q=is%3Aissue) and found no similar issues. ### What happened On first startup of DevLake v1.0.3-beta9 with **MySQL 8.x**, the q_dev plugin migration `20251209000001` fails with SQL syntax errors because it uses `ADD COLUMN IF NOT EXISTS` and `CREATE INDEX IF NOT EXISTS` syntax. Additionally, the same MariaDB-specific pattern was introduced again in migration `20260220000001` (merged to main after v1.0.3-beta9, not yet released). These are **MariaDB-specific extensions** and are **not supported by MySQL 8.x** ([MySQL ALTER TABLE docs](https://dev.mysql.com/doc/refman/8.0/en/alter-table.html)). The Config UI shows **"Operation failed."** messages for the q_dev plugin migrations, causing confusion for users even though the q_dev plugin itself may not be in use. **Actual error logs from MySQL 8.x (4 errors from migration `20251209000001`):** ``` Error 1064 (42000): You have an error in your SQL syntax; ... near 'IF NOT EXISTS scope_id VARCHAR(255) DEFAULT NULL' at line 2 ALTER TABLE _tool_q_dev_user_data ADD COLUMN IF NOT EXISTS scope_id VARCHAR(255) DEFAULT NULL Error 1064 (42000): You have an error in your SQL syntax; ... near 'IF NOT EXISTS idx_q_dev_user_data_scope_id ON _tool_q_dev_user_data(scope_id)' at line 1 CREATE INDEX IF NOT EXISTS idx_q_dev_user_data_scope_id ON _tool_q_dev_user_data(scope_id) Error 1064 (42000): You have an error in your SQL syntax; ... near 'IF NOT EXISTS scope_id VARCHAR(255) DEFAULT NULL' at line 2 ALTER TABLE _tool_q_dev_s3_file_meta ADD COLUMN IF NOT EXISTS scope_id VARCHAR(255) DEFAULT NULL Error 1064 (42000): You have an error in your SQL syntax; ... near 'IF NOT EXISTS idx_q_dev_s3_file_meta_scope_id ON _tool_q_dev_s3_file_meta(scope_' at line 1 CREATE INDEX IF NOT EXISTS idx_q_dev_s3_file_meta_scope_id ON _tool_q_dev_s3_file_meta(scope_id) ``` <img width="970" height="409" alt="Image" src="https://github.com/user-attachments/assets/d612b1d5-8b5c-42cd-8b79-4034dd7c221a" /> ### What do you expect to happen All migrations should succeed without errors on MySQL 8.x. The migration scripts should use database-agnostic patterns (e.g., `db.HasColumn()` + `db.AddColumn()` from the DAL interface) instead of MariaDB-specific syntax. ### How to reproduce 1. Deploy DevLake v1.0.3-beta9 with **MySQL 8.x** as the database backend 2. Start DevLake for the first time (or upgrade from a version without the q_dev tables) 3. Observe the Config UI showing "Operation failed." messages for q_dev migrations ### Anything else **Affected files:** 1. [`backend/plugins/q_dev/models/migrationscripts/20251209_add_scope_id_fields.go`](https://github.com/apache/incubator-devlake/blob/main/backend/plugins/q_dev/models/migrationscripts/20251209_add_scope_id_fields.go) — **included in v1.0.3-beta9, confirmed reproducible** - Uses `ADD COLUMN IF NOT EXISTS` on `_tool_q_dev_user_data` and `_tool_q_dev_s3_file_meta` - Uses `CREATE INDEX IF NOT EXISTS` on both tables 2. [`backend/plugins/q_dev/models/migrationscripts/20260220_add_account_id_to_s3_slice.go`](https://github.com/apache/incubator-devlake/blob/main/backend/plugins/q_dev/models/migrationscripts/20260220_add_account_id_to_s3_slice.go) — **not yet released, but likely affected in the next release** (merged to main after v1.0.3-beta9; uses the same `ADD COLUMN IF NOT EXISTS` pattern) - Uses `ADD COLUMN IF NOT EXISTS` on `_tool_q_dev_s3_slices` **Root cause:** The q_dev plugin is the **only plugin** in DevLake that uses raw `ADD COLUMN IF NOT EXISTS` / `CREATE INDEX IF NOT EXISTS` SQL. All other plugins use the database-agnostic DAL interface (`migrationhelper.AutoMigrateTables()`, `db.HasColumn()`, `db.AddColumn()`, etc.). Note: The existing fallback code (`if err != nil { _ = db.Exec(...) }`) partially mitigates the `ADD COLUMN` issue on fresh installs (the initial syntax error triggers the fallback which succeeds), so the migration can be completed by ignoring the "Operation failed." message and proceeding. However: - The `CREATE INDEX IF NOT EXISTS` has **no fallback** — errors are silently discarded with `_ =`, so **indexes are never created on MySQL** - The initial syntax errors are surfaced in the Config UI as "Operation failed.", causing user confusion **Related:** - [#8564](https://github.com/apache/incubator-devlake/issues/8564) — Same class of bug in q_dev plugin (PostgreSQL-incompatible `MODIFY` syntax), fixed by [#8565](https://github.com/apache/incubator-devlake/pull/8565) using `db.HasColumn()` + `db.Dialect()` switch **Suggested fix:** Replace MariaDB-specific syntax with DAL-native methods, following the same pattern established by [#8565](https://github.com/apache/incubator-devlake/pull/8565): For `ADD COLUMN`: ```go // Before (MariaDB-specific, fails on MySQL 8.x): err := db.Exec(`ALTER TABLE _tool_q_dev_user_data ADD COLUMN IF NOT EXISTS scope_id VARCHAR(255) DEFAULT NULL`) if err != nil { _ = db.Exec(`ALTER TABLE _tool_q_dev_user_data ADD COLUMN scope_id VARCHAR(255) DEFAULT NULL`) } // After (database-agnostic): if !db.HasColumn("_tool_q_dev_user_data", "scope_id") { if err := db.AddColumn("_tool_q_dev_user_data", "scope_id", dal.Varchar); err != nil { return errors.Default.Wrap(err, "failed to add scope_id to _tool_q_dev_user_data") } } ``` For `CREATE INDEX`: ```go // Before (MariaDB-specific, fails on MySQL 8.x): _ = db.Exec(`CREATE INDEX IF NOT EXISTS idx_q_dev_user_data_scope_id ON _tool_q_dev_user_data(scope_id)`) // After (works on both MySQL and PostgreSQL — duplicate index error is a safe runtime error, not a syntax error): _ = db.Exec(`CREATE INDEX idx_q_dev_user_data_scope_id ON _tool_q_dev_user_data(scope_id)`) ``` ### Version DevLake: v1.0.3-beta9, Database: MySQL 8.x ### Are you willing to submit PR? - [x] Yes I am willing to submit a PR! ### Code of Conduct - [x] I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
