Přeskočit na obsah

Explicitní null v INSERTu přebije DEFAULT sloupce → NOT NULL violation

import { Aside } from ‘@astrojs/starlight/components’;

Objednávkový endpoint padá s null value in column "gallery_id" of relation "…" violates not-null constraint — ale jen pro NĚKTERÉ typy objednávek. Jiné typy (ty „nové”, kvůli kterým se sloupec zaváděl) fungují. Sloupec přitom má DEFAULT 1, takže „by to přece mělo projít i bez hodnoty”.

Nová feature (rezervace s vazbou na konkrétní entitu) přidala do sdíleného INSERTu vypočtený sloupec:

let exhibitionGalleryId: number | null = null;
if (isExhibitionSlug(service.slug)) {
exhibitionGalleryId = galleryIdForServiceSlug(service.slug); // jen pro výstavy
}
// ...
await db.from('promo_orders').insert({
artist_id: user.id,
gallery_id: exhibitionGalleryId, // ❌ pro ne-výstavní služby EXPLICITNÍ null
...
});

Rozdíl, na kterém to stojí: DEFAULT se uplatní jen když sloupec v INSERTu chybí. Explicitně poslané NULL je legitimní hodnota, DEFAULT nepřepíše — a na NOT NULL sloupci shodí constraint. Vývojář feature testoval jen „svou” větev (výstavy, kde helper vrací číslo); všechny ostatní větve sdíleného INSERTu tiše rozbil.

Fallback přímo v insertu (nebo klíč vynechat, když je null):

gallery_id: exhibitionGalleryId ?? 1, // ✅ ne-výstavní služby patří defaultní entitě

Jak se tomu vyvarovat v jiných systémech

Sekce “Jak se tomu vyvarovat v jiných systémech”
  • Detection: grep INSERTů na vzor sloupec: nullableHelper( u sloupců s NOT NULL. V code review otázka: „může tahle proměnná být null, a má sloupec DEFAULT?” Test MUSÍ pokrýt i větve, kde se helper nevyhodnotí (tj. ostatní typy objednávek, ne jen ten nový).
  • Anti-pattern: jeden sdílený INSERT pro víc typů záznamů + nový sloupec relevantní jen pro jeden typ, dosazovaný napřímo z X | null proměnné.
  • Lepší přístup: buduj insert objekt podmíněně (...(id != null && { gallery_id: id })), nebo drž fallback na DB default hodnotu explicitně v kódu. A po nasazení feature ověř i JINÉ typy záznamů, které sdílejí stejný INSERT.

Sister bugs / související

Sekce “Sister bugs / související”

Stejná past v UPDATE: col = COALESCE($1, col) vs. přímé dosazení null. A obráceně — spolehnutí na DEFAULT tam, kde ORM (Prisma apod.) posílá všechny sloupce vždy, takže DEFAULT nikdy nenastoupí.

Přidal aiarchitekt.cz · 2. 7. 2026 2:00
Provozuje aiarchitekt.cz