Skip to content

Fix DBI::buildFieldDefinition for null defaults#80

Merged
kennethphough merged 1 commit into
masterfrom
hotfix/dbi-null-default
Apr 25, 2026
Merged

Fix DBI::buildFieldDefinition for null defaults#80
kennethphough merged 1 commit into
masterfrom
hotfix/dbi-null-default

Conversation

@kennethphough

@kennethphough kennethphough commented Apr 25, 2026

Copy link
Copy Markdown
Member

Summary

  • Four-line fix to DBI::buildFieldDefinition so a field declared with 'default' => null emits valid DEFAULT NULL SQL instead of a dangling DEFAULT that MariaDB rejects.
  • Characterization test (testCreateTableAcceptsNullDefault) covering the regression.

Why

Application model's language field carries 'default' => null. Any fresh DBI::createTable(Application) has been blowing up since that field was added — existing customer installs are unaffected because the table already exists. The bug was uncovered while writing a Phase 2 MCP integration test that needed a fresh Application table.

gust/lib/Database.php contains an identical copy of this bug. Patching gust is out of scope for this PR (separate initiative per design doc §11); noted in the commit message for the next gust-refresh session.

Test plan

  • docker compose -f tests/docker-compose.test.yml run --rm php vendor/bin/phpunit --testsuite unit green locally (31/31)
  • CI green on this PR
  • Visual spot-check that DEFAULT NULL appears in SHOW CREATE TABLE for a field with 'default' => null

Before: a field declared with `'default' => null` generated invalid SQL
because the is_string() check fell through and concatenated null (which
PHP coerces to empty string). Result: `\`language\` varchar(5) DEFAULT  NOT NULL,`
with a dangling space, which MariaDB rejects with a syntax error.

After: emit `DEFAULT NULL` explicitly, which is valid SQL and matches
what `'default' => null` obviously intended.

The Application model's `language` field carries `'default' => null`,
so any fresh call to `DBI::createTable(Application)` has been blowing up
since that field was introduced. The bug hasn't surfaced in production
because existing customer installs created the Application table before
the field was added — only fresh installs hit it.

gust/lib/Database.php carries an identical copy of this bug. Patching
gust's copy is explicitly out of scope for the MCP/auth migration
initiative (see design doc section 11 — gust evaluation) and stays on
the "fix when gust is next touched" list.

Added a characterization test in tests/DatabaseTest.php that creates a
throwaway table with a `'default' => null` column and asserts both
success and `DEFAULT NULL` in the resulting SHOW CREATE TABLE output.
The test explicitly re-selects the kytedev database because the
preceding createDatabase tests leave the mysqli connection without an
active database context.

31/31 unit tests green.
@kennethphough
kennethphough merged commit 6913cab into master Apr 25, 2026
2 checks passed
@kennethphough
kennethphough deleted the hotfix/dbi-null-default branch April 25, 2026 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant