Skip to content

Commit 2cd7439

Browse files
committed
wip: changeset
1 parent 82a4d92 commit 2cd7439

1 file changed

Lines changed: 51 additions & 0 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
"@objectstack/cli": patch
3+
---
4+
5+
fix(cli): a generated migration carries the column DEFAULT `driver-sql` puts on the same field (#16294)
6+
7+
## What was wrong
8+
9+
Neither `os generate migration` format read a field's `defaultValue`, so a table
10+
created from a generated migration had no column DEFAULT where the platform's
11+
own table has one. A row inserted out of band — by a database client, a seed
12+
script, anything that does not go through the engine — got NULL where the
13+
declared value belonged.
14+
15+
Driven on live PostgreSQL 16.13: one object, three schemas, one producer each
16+
(`driver-sql` through `initObjects`, `--format sql` through `db.raw`,
17+
`--format ts` by importing the emitted module and calling `up(db)`), with
18+
`information_schema.columns` read back per schema.
19+
20+
```
21+
field driver sqlgen verdict
22+
f_default null=YES default='hello'::text null=YES default=- DIVERGED
23+
f_default_required null=YES default='hello'::text null=YES default=- DIVERGED
24+
```
25+
26+
After: `diverged: 0 of 6` on the card's probe, and 22 of 23 on a wider one
27+
covering every `defaultValue` shape.
28+
29+
## What changed
30+
31+
Both formats now render one shared verdict, taken from
32+
`SqlDriver.applyDeclaredColumnDefault` — the single place a `defaultValue`
33+
becomes DDL on the platform side:
34+
35+
- a **literal** is emitted, quoted the way knex binds it (`DEFAULT '42'`, not
36+
`DEFAULT 42` — PostgreSQL keeps those two textually apart forever in
37+
`column_default`, and the driver's column carries the quoted form);
38+
- **`'NOW()'`** becomes the driver's own translation, which is type-branched:
39+
`CURRENT_TIMESTAMP` on a timestamp column, and a UTC-pinned expression on
40+
`date` / `time`, because a bare `CURRENT_TIMESTAMP` resolves those in the
41+
server's timezone;
42+
- **any other runtime token** (`current_user`), an **Expression envelope** and
43+
an **option-level `default: true`** emit nothing, each because the driver
44+
emits nothing — the engine owns those, and a column DEFAULT would override a
45+
decision it makes deliberately;
46+
- a **`multiple: true`** field gets neither, because `createColumn` returns
47+
before both questions.
48+
49+
No authorable key, export or accepted-input set changes: `defaultValue` was
50+
already declared, already parsed and already honoured by the driver. The
51+
generators simply now read it.

0 commit comments

Comments
 (0)