Skip to content

fix: improve DDL parsing for CHECK/CONSTRAINT/FOREIGN KEY #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 21, 2025

Conversation

LouisBrunner
Copy link
Contributor

  • Do only one thing
  • Non breaking API changes
  • Tested

What did this pull request do?

Currently, the parsing of the DDL ignores some columns (if they start with check or constraint) and add ones that aren't really column (if you have a constraint without CONSTRAINT in front, which is valid). This PR focuses on supporting such cases.

FOREIGN KEY

Example: CREATE TABLE Docs (ID int NOT NULL,UserID int NOT NULL,FOREIGN KEY (UserID) REFERENCES Users(ID))

Explanation: As you don't need to have CONSTRAINT to specify a constraint, it is possible to have a DB which has been created without them and the current parser will consider that a column. This will of course fail when trying to recreate the table as the INSERT INTO () SELECT generated is invalid.

Solution: Because it contains a space, it can easily be detected, just like PRIMARY KEY.

CHECK

Example: CREATE TABLE Docs (ID int NOT NULL,Checksum text NOT NULL)

Explanation: The current parser will ignore any column which starts with CHECK, this works when it is actually a check (e.g. CHECK (Age > 25)) but fails if you just have a column that happens to be named something like checksum (which is valid).

Solution: instead of just checking for a prefix, we use a regexp to detect if something looks like CHECK ( (including any number or whitespace between CHECK and ().

CONSTRAINT

Same deal as CHECK, the only difference is the final regexp which is a bit more complex, checking that CONSTRAINT is followed by a name.

@grandwizard28
Copy link

Hi,
I just came across this PR and was wondering if you are planning to support UNIQUE as well.

The following is not being parsed correctly:

CREATE TABLE IF NOT EXISTS "users" ("id" text NOT NULL, "display_name" text NOT NULL, "email" text NOT NULL, PRIMARY KEY ("id"), UNIQUE ("email"), FOREIGN KEY ("org_id") REFERENCES "organizations" ("id"));

This PR will address FOREIGN KEY but it still won't work with UNIQUE

@LouisBrunner
Copy link
Contributor Author

@grandwizard28 Added.

You can use

replace gorm.io/driver/sqlite v1.6.0 => github.com/aica-technology/sqlite v0.0.0-20250630152124-ead9125b9801

In your go.mod until this PR get merged.

@grandwizard28
Copy link

Awesome!

@jinzhu jinzhu merged commit fc0cfd3 into go-gorm:master Jul 21, 2025
3 checks passed
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.

3 participants