Skip to content

ALTER COLUMN ... DROP DEFAULT incorrectly sets DEFAULT NULL on nullable columns #556

Open

Description

@JanJakes

Problem

After ALTER TABLE ... ALTER COLUMN ... DROP DEFAULT, MySQL keeps a nullable column with no default. The driver stores it as DEFAULT NULL, so SHOW CREATE TABLE and strict-mode inserts differ from MySQL.

Reproduction

CREATE TABLE t (id INT, v VARCHAR(10) DEFAULT 'x');
ALTER TABLE t ALTER COLUMN v DROP DEFAULT;
SHOW CREATE TABLE t;
INSERT INTO t (id) VALUES (1);
MySQL Driver
SHOW CREATE TABLE `v` varchar(10) `v` varchar(10) DEFAULT NULL
Insert in strict mode Error 1364: Field 'v' doesn't have a default value Stores NULL
Insert in non-strict mode Stores NULL with warning 1364 Stores NULL
INFORMATION_SCHEMA.COLUMNS.COLUMN_DEFAULT NULL NULL

MySQL results are from MySQL 8.0.46 and 8.4. Driver results are from #555 at 0e17bbd0e034ed3659f35fb87db4a16755741c14, which implements DROP DEFAULT, with PHP 8.5.11 and SQLite 3.54.1.

WordPress is not affected in practice. It disables strict mode, where MySQL also stores NULL, and dbDelta() never drops defaults. The difference matters for PDO and MySQL proxy users in strict mode, and for exports made with SHOW CREATE TABLE.

Cause

A nullable column has two possible states in MySQL:

  • DEFAULT NULL: Every nullable column gets this when it is created without a default.
  • No default: Only DROP DEFAULT produces this.

INFORMATION_SCHEMA shows NULL for both. The driver keeps defaults only in its information schema tables, so it can't tell them apart. The SQLite table can't express the second state either, because SQLite always stores NULL in an omitted nullable column.

Direction

  • Store a private "no default" flag for nullable columns, for both permanent and temporary tables. It must not appear in the emulated INFORMATION_SCHEMA tables.
  • Omit DEFAULT NULL from SHOW CREATE TABLE for these columns.
  • Reject strict-mode inserts that omit the column with error 1364. Also check how MySQL handles DEFAULT in VALUES, INSERT ... SELECT, and REPLACE.
  • Clear the flag on SET DEFAULT, CHANGE, and MODIFY, and when the column or table is dropped. Keep it through table rebuilds.

The strict-mode table in translate_insert_or_replace_body() says that a nullable column without a default saves NULL when omitted. That describes DEFAULT NULL, not this state.

Related

Activity

  1. changed the title [-]ALTER COLUMN ... DROP DEFAULT on a nullable column is stored as DEFAULT NULL[/-] [+]`ALTER COLUMN ... DROP DEFAULT` incorrectly sets `DEFAULT NULL` on nullable columns[/+] on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions