Skip to content
Astera Technology

Why does an old orphan remain after foreign keys are enabled?

Inspect actual historical violations before releasing the loaded database.

Download complete case notes and answer keys ↓

Read the source and its declared rule

The original legacy load occurred with enforcement explicitly OFF. Turning ON protects subsequent applicable writes but does not repair the existing child pointing to absent parent 1. This release gate requires foreign_key_check to return no violations.

Filled synthetic input
RecordInput JSON
Base input{"parentPresent":false,"childPresent":true}
Download editable CSV ↓

Compare the actual paths

Correct output holds release and identifies child row 1, parent table, FK index 0. It preserves that legacy row for correction rather than announcing it disappeared when enforcement changed.

Misleading and corrected outputs
PathOutput JSON
Misleading path{"released":true,"violations":null,"children":[{"id":1,"parent_id":1}]}
Corrected path{"released":false,"violations":[{"table":"child","rowid":1,"parent":"parent","fkid":0}],"children":[{"id":1,"parent_id":1}]}
Download editable CSV ↓
Local Node.js program: 22.23.3 or 24.14.1
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};

import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
    const db=new DatabaseSync(':memory:');try{db.exec('PRAGMA foreign_keys=OFF;CREATE TABLE parent(id INTEGER PRIMARY KEY);CREATE TABLE child(id INTEGER PRIMARY KEY,parent_id INTEGER REFERENCES parent(id));');
      if(i.parentPresent)db.exec('INSERT INTO parent VALUES(1);');if(i.childPresent)db.exec('INSERT INTO child VALUES(1,1);');
      db.exec('PRAGMA foreign_keys=ON;');const violations=corrected?rows(db,'PRAGMA foreign_key_check'):null;
      return {released:!corrected||violations.length===0,violations,children:rows(db,'SELECT * FROM child')};
    }finally{db.close();}
  };
const cases=[{"label":"misleading base","input":{"parentPresent":false,"childPresent":true},"expected":{"released":true,"violations":null,"children":[{"id":1,"parent_id":1}]},"corrected":false},{"label":"corrected base","input":{"parentPresent":false,"childPresent":true},"expected":{"released":false,"violations":[{"table":"child","rowid":1,"parent":"parent","fkid":0}],"children":[{"id":1,"parent_id":1}]},"corrected":true},{"label":"historical child has matching parent","input":{"parentPresent":true,"childPresent":true},"expected":{"released":true,"violations":[],"children":[{"id":1,"parent_id":1}]},"corrected":true},{"label":"no historical children","input":{"parentPresent":false,"childPresent":false},"expected":{"released":true,"violations":[],"children":[]},"corrected":true}];
for(const test of cases){
  const actual=run(test.input,test.corrected);
  assert.deepEqual(actual,test.expected,test.label);
  console.log(test.label,actual);
}
Download runnable example ↓

Check boundaries before the next load

A matching historical parent passes. No historical child also yields no violations.

Editable boundary records and expected outputs
CaseInput JSONExpected output JSON
Historical link has its parent{"parentPresent":true,"childPresent":true}{"released":true,"violations":[],"children":[{"id":1,"parent_id":1}]}
No historical children{"parentPresent":false,"childPresent":false}{"released":true,"violations":[],"children":[]}
Download editable CSV ↓

Can an ON setting alone certify old loaded rows?

Show the worked answer

No. Run the historical check. This fixture still has one violation and must not release until corrected.

Related resources