Skip to content

sqlc generate fails on MySQL DDL using DEFAULT (UTC_TIMESTAMP()) / ON UPDATE (UTC_TIMESTAMP()) #4178

@2m5g

Description

@2m5g

Version

1.30.0

What happened?

Hello!
First of all, thanks for the great work on sqlc. We rely on it heavily and it has been a huge boost to our project.

We’ve encountered an issue when generating Go code from our MySQL schema.
It appears that sqlc generate fails when encountering expression defaults such as DEFAULT (UTC_TIMESTAMP()) or ON UPDATE (UTC_TIMESTAMP()).

Environment

  • sqlc version: 1.30.0 (also reproduces on latest)
  • Database: MySQL 8.0+ (also MySQL 9.x / Aurora MySQL compatible)
  • SQL Mode: default strict mode (ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, ...)

Summary
sqlc generate fails when parsing MySQL schemas that use expression defaults such as:

created_at TIMESTAMP NOT NULL DEFAULT (UTC_TIMESTAMP()),
updated_at TIMESTAMP NOT NULL DEFAULT (UTC_TIMESTAMP()) ON UPDATE (UTC_TIMESTAMP()),
joined_at  TIMESTAMP NOT NULL DEFAULT (UTC_TIMESTAMP())

MySQL accepts this syntax (valid since 8.0.13 ?), but sqlc’s MySQL parser rejects it.

Expected
sqlc generate should parse these valid MySQL expressions in DEFAULT and ON UPDATE.

Actual

syntax error near "UTC_TIMESTAMP())"

Minimal Repro

  1. Create a migration file, e.g.,:
CREATE TABLE mytable (
  id BIGINT UNSIGNED NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT (UTC_TIMESTAMP())
);
  1. Run sqlc generate

Why this matters

  • UTC_TIMESTAMP() guarantees UTC regardless of session time_zone
  • Production MySQL setups may rely on this pattern (at least I wanted to hence the report)

Possible workaround: Removing defaults is not acceptable, and forcing ALTER later just to satisfy sqlc is undesirable

Suggestion

A) Extend MySQL parser support for DEFAULT () and ON UPDATE ()
B) Even allowing sqlc to ignore expression-defaults in DDL would be acceptable, since default/trigger logic doesn’t affect type generation

Thanks!

M

Relevant log output

syntax error near "UTC_TIMESTAMP()),"

Database schema

CREATE TABLE mytable (
  id BIGINT UNSIGNED NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT (UTC_TIMESTAMP()),
);

Configuration

version: "2"

sql:
  # ---- Global DB ----
  - engine: "mysql"
    schema:
      - "./db/migrations/"
    queries:
      - "./db/queries/"
    gen:
      go:
        package: "dbgen"
        out: "./internal/dbgen/"
        emit_pointers_for_null_types: true
        overrides:
          - db_type: "tinyint(1)"
            go_type: "bool"

Playground URL

No response

What operating system are you using?

No response

What database engines are you using?

MySQL

What type of code are you generating?

Go

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions