fix(migrator): carve out MySQL in addColumnOptionsSpec text-default assertion - #2748
Conversation
…ssertion Closes #2742. Follow-up to #2661/#2669. `addColumnOptionsSpec :: text with a real default (non-empty) still emits DEFAULT` failed on every MySQL leg of the compat matrix (lucee6/mysql, lucee7/mysql, boxlang/mysql) with the assertion message `The needle [DEFAULT] was not found in [ NULL]`. The MySQL adapter's `optionsIncludeDefault` intentionally returns false for `text`, `mediumtext`, `longtext`, and `float`, so the inherited Abstract `addColumnOptions` short-circuits the entire DEFAULT clause for those types — emitting only the `NULL`/`NOT NULL` suffix. The pre-8.0.13 MySQL constraint that TEXT/BLOB columns reject DEFAULT is what motivates the suppression, and the framework targets the broadest supported MySQL surface rather than emitting DDL that fails on older servers. The spec now mirrors the existing `isPostgresFamily` adapter-aware pattern: a new `variables.isMySQLFamily` flag in `beforeAll` carves out the MySQL branch, asserting `notToInclude("DEFAULT")` while every other Abstract-based adapter continues to assert `toInclude("DEFAULT")` plus `toInclude("'long body'")`. Header doc-comment updated to document the MySQL divergence alongside the PG/CockroachDB one. `MySQLMigrator.optionsIncludeDefault`'s one-line doc-comment was expanded to explain WHY (legacy MySQL TEXT/BLOB constraint), what the user-visible behavior is (non-empty default silently suppressed), and to reference the spec contract — keeping the suppression list and the test aligned. Pure test + doc-comment change. No production behavior delta. Verified locally: full SQLite core-test run unchanged (0 failures, 0 errors) before and after the edit. CI matrix will validate the MySQL legs. Signed-off-by: wheels-bot[bot] <283220952+wheels-bot[bot]@users.noreply.github.com>
…ompat guide MySQLMigrator.optionsIncludeDefault returns false for text-family and float columns, causing addColumnOptions to silently drop the DEFAULT clause — even for non-empty defaults. Mirrors the existing isPostgresFamily note with an isMySQLFamily carve-out example. Surfaced by #2742 / PR #2748. Signed-off-by: wheels-bot[bot] <wheels-bot[bot]@users.noreply.github.com> Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Wheels Bot — Docs updatedAdded a doc commit to this PR:
No MDX user-guide changes: no user-visible behavior delta (the MySQL suppression was pre-existing). No CLAUDE.md changes: no model/controller/view convention affected. |
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: This is a minimal, well-scoped fix that carves out MySQL from the addColumnOptionsSpec text+non-empty-default assertion, mirroring the existing isPostgresFamily pattern introduced in #2669. The production behavior is unchanged — the spec is being corrected to reflect what the MySQL adapter has always done. I have two minor nits and no blocking concerns; submitting as a comment.
Correctness
The fix is correct. MySQLMigrator.optionsIncludeDefault (line 82) returns false for text, so Abstract.addColumnOptions (line 74) short-circuits the DEFAULT clause before the assertion ever reaches it. The original spec asserted toInclude("DEFAULT") unconditionally, which was wrong on MySQL. The carve-out accurately documents existing adapter behavior rather than changing it.
The new isMySQLFamily guard is also complete: MySQL is the only MySQL-family adapter in the codebase (no MariaDB adapter exists; the only adapterName() implementations are MySQL, PostgreSQL, CockroachDB, SQLite, H2, Oracle, MicrosoftSQLServer).
Conventions
Nit — misleading it() description (vendor/wheels/tests/specs/migrator/addColumnOptionsSpec.cfc line 102):
it("text with a real default (non-empty) still emits DEFAULT", () => {
...
if (variables.isMySQLFamily) {
expect(sql).notToInclude("DEFAULT"); // contradicts the description
} else {
expect(sql).toInclude("DEFAULT");
}
});The test name says "still emits DEFAULT" but the MySQL branch asserts the exact opposite. A future reader opening a MySQL CI failure will see a passing test named "text with a real default (non-empty) still emits DEFAULT" whose body asserts notToInclude("DEFAULT") — the mismatch will slow down diagnosis. Consider a neutral description such as "text with a real default (non-empty): DEFAULT clause is adapter-dependent", or split into two it() blocks.
Docs
Nit — CHANGELOG omits #2669 (CHANGELOG.md line 40):
The commit message body and PR description both read "Follow-up to #2661/#2669", where #2669 is the PR that introduced the isPostgresFamily pattern this change explicitly mirrors. The CHANGELOG entry says only "Follow-up to #2661", dropping the direct precedent. One-word fix.
Commits
Single commit fix(migrator): carve out MySQL in addColumnOptionsSpec text-default assertion — valid type, valid scope, 62-char subject, sentence-case, DCO sign-off present. Clean.
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: One new commit has landed since the previous review (a9e5f4d): 5f54e39b6 docs: document MySQL TEXT/FLOAT DEFAULT suppression in cross-engine-compat guide. It adds a well-placed, accurate section to .ai/wheels/cross-engine-compatibility.md and is clean on every axis I check. The two minor nits flagged in the prior review remain unaddressed. Submitting as a comment — no new blocking issues.
Commits
The new commit is docs type, no scope, 72-char subject (under the 100-char cap), sentence-case, DCO sign-off present on both bot identities. Conforms to commitlint.config.js.
The commit body correctly describes the why (silently drops DEFAULT on TEXT/FLOAT because pre-8.0.13 MySQL rejects it) and references the surfacing issue (#2742 / PR #2748). Clean.
Docs
The new section in .ai/wheels/cross-engine-compatibility.md is accurate:
MySQLMigrator.optionsIncludeDefaultdoes returnfalsefortext,mediumtext,longtext, andfloat— confirmed against the adapter source.- The
Abstract.addColumnOptionsshort-circuit is real; the spec change proves it. - Placement between the PostgreSQL section and the CockroachDB section is logical; the code snippet is a verbatim mirror of the
addColumnOptionsSpec.cfcpattern, so future spec authors get a copy-pasteable reference.
No issues with the new content.
Outstanding nits from previous review (a9e5f4d)
Neither prior nit was addressed:
1. Misleading it() description (vendor/wheels/tests/specs/migrator/addColumnOptionsSpec.cfc, line 102):
it("text with a real default (non-empty) still emits DEFAULT", () => {
...
if (variables.isMySQLFamily) {
expect(sql).notToInclude("DEFAULT"); // contradicts the description
} else {
expect(sql).toInclude("DEFAULT");
}
});The inline comment inside the isMySQLFamily branch was added (good), but the it() name still says "still emits DEFAULT" while the MySQL path asserts the exact opposite. A developer seeing a green test named "text with a real default (non-empty) still emits DEFAULT" on a MySQL CI run will be confused. Suggested rename: "text with a real default (non-empty): DEFAULT clause is adapter-dependent".
2. CHANGELOG omits #2669 (CHANGELOG.md, line 40):
The entry ends Follow-up to #2661 — the PR description and commit body both reference #2661/#2669, where #2669 introduced the isPostgresFamily pattern this change explicitly mirrors. One-word fix to include /#2669.
Both are nits with no correctness impact, consistent with the prior review's assessment.
Wheels Bot -- Reviewer B (round 1)A's review is solid: no sycophancy, both nits check out against the actual diff, no false positives. One addendum: A reviewed against SHA SycophancyNone detected. A correctly identified two actionable nits and submitted False positivesNone detected.
Missed issuesNot a fault in A's review, but worth noting: the docs commit Verdict alignmentA's ConvergenceAligned on |
Wheels Bot — Reviewer B (round 1)A's review is clean and accurate on the new docs commit. Both carry-over nits are verified against the diff. No sycophancy, no false positives, no missed issues. Converging with changes needed to apply the two nits. SycophancyNone detected. A's verdict is False positivesNone detected.
Missed issuesNone detected. The new docs section in Verdict alignmentA's ConvergenceAligned. Both nits are real, unaddressed, and concretely specified — address-review has enough detail to apply them. Joint recommendation: rename the |
- Rename the `it()` description at addColumnOptionsSpec.cfc:102 from
"text with a real default (non-empty) still emits DEFAULT" to
"text with a real default (non-empty): DEFAULT clause is adapter-dependent".
The old name contradicted the MySQL branch's `notToInclude("DEFAULT")`
assertion. The neutral name surfaces the adapter-dependence in CI failure
reports.
- CHANGELOG.md: append `/#2669` to the trailer of the Fixed entry. The PR
description and commit body both cite "#2661/#2669", but the CHANGELOG
trailer dropped #2669 — which is the PR that introduced the
`isPostgresFamily` carve-out this change explicitly mirrors.
Pure text changes: no executable test logic touched, no production code
delta. Test runner not available in the address-review CI environment
(no `wheels` CLI installed); `test-local.sh` portability bug aside, neither
edit can regress test execution.
Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Wheels Bot — Address Review (round 1)Applied consensus findings from Reviewer A and Reviewer B's convergence (round 1):
Both edits are text-only. The test description is the first arg to Test re-run skipped this round: the address-review environment has no The new commit will trigger a fresh Reviewer A run on the updated SHA. Convergence loop continues until reviewers align on |
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: The new commit (7303d4b5f) resolves both outstanding nits from the prior two reviews: the it() description no longer contradicts the MySQL assertion branch, and the CHANGELOG trailer now cites #2661/#2669 as intended. No new issues. This PR is clean and ready for a human approval.
Prior findings — now resolved
Nit 1 — Misleading it() description (vendor/wheels/tests/specs/migrator/addColumnOptionsSpec.cfc, line 102):
Old name: "text with a real default (non-empty) still emits DEFAULT"
New name: "text with a real default (non-empty): DEFAULT clause is adapter-dependent"
The renamed description is neutral and accurate. A developer seeing a green MySQL CI run will no longer face a test name that says "still emits DEFAULT" while the body asserts notToInclude("DEFAULT"). Resolved.
Nit 2 — CHANGELOG omits #2669 (CHANGELOG.md, line 40):
The entry now ends Follow-up to #2661/#2669, correctly referencing the PR that introduced the isPostgresFamily carve-out this change mirrors. Resolved.
Commits
New commit fix(migrator): address Reviewer A/B consensus findings (round 1) — valid type, valid scope, 54-char subject, sentence-case, DCO sign-off present. Commit body explains the why for both changes. Conforms to commitlint.config.js. Clean.
All three commits in this PR are clean on every axis checked (correctness, conventions, cross-engine compatibility, tests, docs, commits, security). No blocking or advisory findings remain.
Wheels Bot — Reviewer B (round 1)A's review checks out on the new SHA. Both nits from the prior round are verified as resolved; A's verdict is consistent with the findings; no sycophancy, no false positives, no missed issues on the diff I re-scanned. Converging on approve. SycophancyNone detected. A's state is False positivesNone detected.
Missed issuesNone detected. The full PR diff (three commits) covers: the Verdict alignmentA's ConvergenceAligned. Both nits are resolved and verified against the diff. No remaining findings. Joint recommendation: this PR is review-clean on the current SHA and ready for human approval. |
…c-text-default-default
There was a problem hiding this comment.
Wheels Bot — Reviewer A
TL;DR: The current head SHA (d27fd9e3e) is a merge-from-develop commit that pulled in PR #2746 (the CockroachDB $supportsAdvisoryLocks override). None of this PR's own files were touched by that merge — the four changed files in the PR (addColumnOptionsSpec.cfc, MySQLMigrator.cfc, .ai/wheels/cross-engine-compatibility.md, CHANGELOG.md) are identical at this SHA to what was reviewed at 7303d4b5f. All prior nits from the three preceding reviews were fully resolved at that SHA. No new findings. Submitting as a comment — this PR merged clean.
Status of prior findings (all resolved)
| Finding | File | Resolved at |
|---|---|---|
Misleading it() description contradicted the MySQL assertion branch |
addColumnOptionsSpec.cfc line 102 |
7303d4b5f |
CHANGELOG entry omitted #2669 from the Follow-up to trailer |
CHANGELOG.md line 40 |
7303d4b5f |
Merge-from-develop delta
The two files introduced by the develop merge (CHANGELOG.md and vendor/wheels/databaseAdapters/CockroachDB/CockroachDBModel.cfc) are unrelated to this PR's scope and were reviewed independently as part of PR #2746. They have no interaction with the MySQL optionsIncludeDefault path changed here.
Wheels Bot -- Reviewer B (round 1)A's review is accurate. The current head is a merge-from-develop commit; verified via SycophancyNone detected. A explicitly identified and verified the merge delta rather than issuing a blanket LGTM. The False positivesNone detected.
Missed issuesNone detected. The merge delta ( Verdict alignmentA's ConvergenceAligned. A's assessment is accurate and fully supported by the diff. Joint recommendation: this PR is review-clean on the current SHA and ready for human approval. No further bot iterations needed. |
Summary
Fixes the last failing leg of the
addColumnOptionsSpeccross-engine matrix. The spec's"text with a real default (non-empty) still emits DEFAULT"assertion failed on every MySQL leg (lucee6/mysql, lucee7/mysql, boxlang/mysql) withThe needle [DEFAULT] was not found in [ NULL]. The MySQL adapter intentionally suppresses the entire DEFAULT clause fortext/mediumtext/longtext/floatcolumns (MySQLMigrator.optionsIncludeDefaultreturns false, and the inheritedAbstract.addColumnOptionsshort-circuits) because pre-MySQL-8.0.13 rejects DEFAULT on TEXT/BLOB outright. The spec now adds avariables.isMySQLFamilycarve-out that mirrors the existingisPostgresFamilyadapter-aware pattern from #2669.The MySQL adapter's one-line
optionsIncludeDefaultdoc-comment was also expanded to document the rationale and reference the spec contract, so future maintenance touches both sides of the invariant.Pure test + doc-comment change — no production behavior delta. Verified locally: full SQLite core-test run unchanged (0 failures, 0 errors) before and after the edit. CI matrix will validate the MySQL legs.
Related Issue
Closes #2742
Type of Change
Feature Completeness Checklist
Signed-off-by: wheels-bot[bot]addColumnOptionsSpecupdated; failing-on-MySQL → passing-on-allbot-update-docs.ymlwill follow up if neededbot-update-docs.ymlwill follow up if neededbot-update-docs.ymlwill follow up if needed[Unreleased] → FixedaddColumnOptionsSpec7 pass / 0 failTest Plan
addColumnOptionsSpecstill 7/7 on SQLite (Lucee 7) — full core run, 0 failures, 0 errorsNotes for reviewers
vendor/wheels/migrator/**auto-downgrade concern. A strict reading of the auto-downgrade rule applies tovendor/wheels/migrator/**; the files changed here arevendor/wheels/tests/specs/migrator/(spec) andvendor/wheels/databaseAdapters/MySQL/(adapter doc-comment), neither of which is undervendor/wheels/migrator/. The change shape matches the precedent in fix(migrator): make addColumnOptions spec adapter-aware and fix PG empty-default spacing #2669 (also bot-authored) that the triage explicitly told the bot to mirror.