Read the source and its declared rule
The original import owns display only for an existing id. Local note Keep must survive incoming display New with note null. A genuinely new id may use the supplied initial note. The corrected UPSERT updates display on conflict while its insert branch retains the separate initial-row rule.
| Record | Input JSON |
|---|---|
| Base input | {"id":1,"display":"New","note":null} |
Compare the actual paths
Bad conflict update makes note null. Corrected id 1 has display New and note Keep; approving one source-owned field does not transfer ownership of the entire row.
| Path | Output JSON |
|---|---|
| Misleading path | [{"id":1,"display":"New","note":null}] |
| Corrected path | [{"id":1,"display":"New","note":"Keep"}] |
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("CREATE TABLE target(id INTEGER PRIMARY KEY,display TEXT,note TEXT);INSERT INTO target VALUES(1,'Old','Keep');");
db.prepare('INSERT INTO target VALUES(?,?,?) ON CONFLICT(id) DO UPDATE SET display=excluded.display'+(corrected?'':',note=excluded.note')).run(i.id,i.display,i.note);
return rows(db,'SELECT * FROM target ORDER BY id');
}finally{db.close();}
};
const cases=[{"label":"misleading base","input":{"id":1,"display":"New","note":null},"expected":[{"id":1,"display":"New","note":null}],"corrected":false},{"label":"corrected base","input":{"id":1,"display":"New","note":null},"expected":[{"id":1,"display":"New","note":"Keep"}],"corrected":true},{"label":"new record has supplied initial note","input":{"id":2,"display":"New","note":"Initial"},"expected":[{"id":1,"display":"Old","note":"Keep"},{"id":2,"display":"New","note":"Initial"}],"corrected":true},{"label":"permitted empty display value","input":{"id":1,"display":"","note":null},"expected":[{"id":1,"display":"","note":"Keep"}],"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);
}
Check boundaries before the next load
New id 2 receives Initial. A permitted empty display on existing 1 still preserves Keep.
| Case | Input JSON | Expected output JSON |
|---|---|---|
| Initial note for a new row | {"id":2,"display":"New","note":"Initial"} | [{"id":1,"display":"Old","note":"Keep"},{"id":2,"display":"New","note":"Initial"}] |
| Empty display on an existing row | {"id":1,"display":"","note":null} | [{"id":1,"display":"","note":"Keep"}] |
Should the incoming null clear Keep on existing id 1?
Show the worked answer
No. Note is target-owned on an existing row. Update display only, leaving Keep intact.