Skip to content

Validate and normalize literal column defaults like MySQL #551

Open

Description

@JanJakes

Problem

MySQL converts a column default to the column's type when a table is created, and it rejects defaults that can't be converted. The driver stores most literal defaults exactly as written. SHOW CREATE TABLE, INFORMATION_SCHEMA.COLUMNS, and the values of new rows can then differ from MySQL, and some exports don't import into MySQL.

Column definition Driver MySQL
TIME DEFAULT '0' '0' '00:00:00'
DATETIME DEFAULT '0' '0' Error 1067 (strict mode)
YEAR DEFAULT '0' '0' '2000'
DATE DEFAULT 20200102 '20200102' '2020-01-02'
INT DEFAULT 1.0 '1.0' '1'
INT DEFAULT 1e3 '1e3' '1000'
INT DEFAULT 0x10 '0x10' '16'
VARCHAR(10) DEFAULT 0x61 '0x61' 'a'
VARCHAR(10) DEFAULT _utf8mb4'abc' '_utf8mb4abc' 'abc'

The driver values are from SHOW CREATE TABLE on trunk (3.1.0).

Direction

Validate and normalize each literal default from its AST node and the full column definition, as MySQL does: convert it to the column's type, store the resulting value, and reject defaults that can't be converted with error 1067. The @TODO in get_literal_default() lists the known cases.

Related

These fix parts of this:

Activity

  1. JanJakes commented on Oct 22, 2026

    @JanJakes
    MemberAuthor

    Some more cases, found while reviewing #555:

    Binary columns. Literal defaults on BINARY and VARBINARY columns are stored as text, so every insert that omits the column fails with cannot store TEXT value in BLOB column:

    CREATE TABLE t (id INT, v VARBINARY(8) NOT NULL DEFAULT '');
    INSERT INTO t (id) VALUES (1); -- fails

    The same happens with DEFAULT 'F', DEFAULT 0x41, and DEFAULT ('F'). Only DEFAULT (0x41) works, because it is treated as an expression. MySQL stores the bytes and shows binary defaults in hex in INFORMATION_SCHEMA.COLUMNS (0x46 for 'F').

    Inserts with hex defaults. INT DEFAULT 0x10 doesn't only show '0x10'. Every insert that omits the column also fails with cannot store TEXT value in INTEGER column.

    Other literal kinds:

    Default Driver MySQL
    N'abc' 'N''abc''' 'abc'
    DATE '2020-01-03' 'DATE2020-01-03' Error 1067 for ALTER ... SET DEFAULT

    ALTER COLUMN. #555 records ALTER ... SET DEFAULT with the same literal handling, so it has the same results. Like MySQL, it treats a parenthesized constant such as (0x41) as a literal.

    A fix could follow the existing BIT handling. Store binary defaults in hex and write them to SQLite as X'…'. For text columns, decode hex and bit literals to their bytes; for numeric columns, convert them to their value. Existing tables may already hold unconverted text such as 0x41.

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