Skip to content

Commit 9b8634b

Browse files
authored
Merge 'translate/upsert: use emit_column_or_rowid for DO UPDATE row snapshot' from ongyimeng
- In core/translate/upsert.rs, conflicting-row snapshots now use emit_column_or_rowid(...) - Replaces manual Column { default: None } handling - Adds regression test in testing/sqltests/tests/upsert.sqltest - UPSERT was reading NULL in cases where SQLite expects the column’s default value - This happens for missing trailing column values after ALTER TABLE ... ADD COLUMN ... DEFAULT ... - The fix restores SQLite-compatible behavior - Applies specifically to the DO UPDATE path of UPSERT Issue #6087 Used AI to trace the issue to upsert.rs, propose the minimal fix, and draft the regression test. Closes #6118
2 parents 8d8c2aa + 1b65689 commit 9b8634b

File tree

3 files changed

+18
-13
lines changed

3 files changed

+18
-13
lines changed

core/translate/upsert.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -411,25 +411,16 @@ pub fn emit_upsert(
411411
let layout = ctx.table.column_layout();
412412

413413
let current_start = program.alloc_registers(num_cols);
414-
for (i, col) in ctx.table.columns.iter().enumerate() {
414+
for i in 0..num_cols {
415+
let col = &table.columns()[i];
415416
let reg = layout.to_register(current_start, i);
416417
if col.is_virtual_generated() {
417418
program.emit_insn(Insn::Null {
418419
dest: reg,
419420
dest_end: None,
420421
});
421-
} else if col.is_rowid_alias() {
422-
program.emit_insn(Insn::RowId {
423-
cursor_id: ctx.cursor_id,
424-
dest: reg,
425-
});
426422
} else {
427-
program.emit_insn(Insn::Column {
428-
cursor_id: ctx.cursor_id,
429-
column: layout.to_reg_offset(i),
430-
dest: reg,
431-
default: None,
432-
});
423+
program.emit_column_or_rowid(ctx.cursor_id, i, reg);
433424
}
434425
}
435426

testing/sqltests/tests/snapshot_tests/returning/snapshots/returning__upsert-returning.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ addr opcode p1 p2 p3 p4 p5 comment
4747
28 SeekRowid 1 1 49 0 if (r[1]!=cursor 1 for table t2.rowid) goto 49
4848
29 RowId 1 15 0 0 r[15]=t2.rowid
4949
30 Column 1 1 16 0 r[16]=t2.name
50-
31 Column 1 2 17 0 r[17]=t2.counter
50+
31 Column 1 2 17 0 0 r[17]=t2.counter
5151
32 Copy 15 18 2 0 r[18]=r[15]
5252
33 Copy 17 21 0 0 r[21]=r[17]
5353
34 Integer 1 22 0 0 r[22]=1

testing/sqltests/tests/upsert.sqltest

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ expect {
8181
1|11|new
8282
}
8383

84+
@cross-check-integrity
85+
test upsert-do-update-reads-added-column-default-for-prealter-row {
86+
CREATE TABLE t(id INTEGER PRIMARY KEY, name TEXT);
87+
INSERT INTO t VALUES(1, 'alice');
88+
ALTER TABLE t ADD COLUMN score INTEGER DEFAULT 42;
89+
90+
INSERT INTO t VALUES(1, 'bob', 0)
91+
ON CONFLICT(id) DO UPDATE SET score = score + 1;
92+
SELECT * FROM t;
93+
}
94+
expect {
95+
1|alice|43
96+
}
97+
8498
@cross-check-integrity
8599
test upsert-values-mixed-insert-update {
86100
CREATE TABLE m (a UNIQUE, b);

0 commit comments

Comments
 (0)