drizzle-team / drizzle-team/drizzle-orm
[BUG]: drizzle-kit pull truncates PostgreSQL NOT VALID check constraints
- Dominant language
- TypeScript
- Stars
- 35.8k
- Forks
- 1.6k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 4
Description
### What version of `drizzle-orm` and `drizzle-kit` are you using?
- `drizzle-orm`: `1.0.0-rc.4`
- `drizzle-kit`: `1.0.0-rc.4`
The same parsing logic is still present in the `rc5` branch at commit [`82aba1ae`](https://github.com/drizzle-team/drizzle-orm/commit/82aba1ae44d28c6b1a0bd905439c51ad1af1e550).
### Describe the bug
When PostgreSQL returns a check constraint definition ending in `NOT VALID`, `drizzle-kit pull` removes the final character of the complete definition instead of extracting the check expression.
For example, a definition such as:
```sql
CHECK ((version >= 0)) NOT VALID
```
is emitted in `schema.ts` as:
```ts
check("documents_version_check", sql`(version >= 0)) NOT VALI`)
```
The migration generated by `pull` consequently contains invalid SQL using `NOT VALI`.
### Reproduction
Create a table and add a `NOT VALID` check constraint:
```sql
CREATE TABLE documents (
id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
version integer NOT NULL
);
ALTER TABLE documents
ADD CONSTRAINT documents_version_check
CHECK (version >= 0) NOT VALID;
```
Run `drizzle-kit pull` against the database and inspect the generated `schema.ts` and migration SQL.
### Expected behavior
The generated check expression should be syntactically valid. Ideally Drizzle should preserve the `NOT VALID` state; if that state is not currently modeled, it should at least not become part of a corrupted SQL expression.
```ts
check("documents_version_check", sql`version >= 0`)
```
### Suspected cause
The PostgreSQL introspector currently assumes that every definition is exactly `CHECK (...)` and removes fixed numbers of characters:
https://github.com/drizzle-team/drizzle-orm/blob/82aba1ae44d28c6b1a0bd905439c51ad1af1e550/drizzle-kit/src/dialects/postgres/introspect.ts#L884-L896
```ts
value: check.definition.startsWith("CHECK (")
? check.definition.slice(7, -1)
: check.definition
```
With `CHECK (...) NOT VALID`, `slice(7, -1)` removes only the final `D` from `VALID`.
Issue found and analyzed using AI tools, in this case gpt-5.6-sol max, but manually reviewed and checked by me.
Contributor guide
Research direction
Start in drizzle-kit/src/dialects/postgres/introspect.ts around lines 884-896 and inspect how PostgreSQL check definitions are parsed. Reproduce the issue with the supplied documents_version_check SQL, run drizzle-kit pull, and inspect schema.ts and the generated migration. Done means the check expression remains syntactically valid without truncating the NOT VALID suffix.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- postgresql, typescript
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100