Skip to content

Commit 726af39

Browse files
committed
Reject rowid-changing updates on virtual tables
1 parent 1a1bc9e commit 726af39

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

sqlite3_opt_vtable.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,14 @@ func goVUpdate(pVTab unsafe.Pointer, argc C.int, argv **C.sqlite3_value, pRowid
609609

610610
case argc > 1:
611611
// Per the xUpdate contract argv[0] identifies the row being
612-
// updated while argv[1] is its (possibly changed) new rowid.
613-
err = v.Update(vals[0], vals[2:])
612+
// updated while argv[1] is its new rowid. VTabUpdater has no
613+
// way to convey a rowid change, so reject it instead of
614+
// silently updating values under the old rowid.
615+
if vals[0] != vals[1] {
616+
err = fmt.Errorf("virtual %s table %sdoes not support changing the rowid", vt.module.name, tname)
617+
} else {
618+
err = v.Update(vals[0], vals[2:])
619+
}
614620
}
615621
}
616622

sqlite3_opt_vtable_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,19 @@ func TestVUpdate(t *testing.T) {
280280
t.Fatalf("expected table vt entry 1 to be [117 f e], instead: %v", vt.data[1])
281281
}
282282

283+
// a rowid-changing update cannot be expressed via VTabUpdater and
284+
// must be rejected instead of updating the wrong row
285+
_, err = db.Exec(`update vt set rowid = rowid + 10 where f1 = 117`)
286+
if err == nil {
287+
t.Fatalf("expected error on rowid-changing update, got nil")
288+
}
289+
if !strings.Contains(err.Error(), "does not support changing the rowid") {
290+
t.Fatalf("unexpected error on rowid-changing update: %v", err)
291+
}
292+
if !reflect.DeepEqual(vt.data[1], []any{int64(117), "f", "e"}) {
293+
t.Fatalf("expected table vt entry 1 to be unchanged, instead: %v", vt.data[1])
294+
}
295+
283296
// delete from vt
284297
res, err = db.Exec(`delete from vt where f1 = 117`)
285298
if err != nil {

0 commit comments

Comments
 (0)