Reject rowid-changing updates on virtual tables
This commit is contained in:
@@ -609,10 +609,16 @@ func goVUpdate(pVTab unsafe.Pointer, argc C.int, argv **C.sqlite3_value, pRowid
|
||||
|
||||
case argc > 1:
|
||||
// Per the xUpdate contract argv[0] identifies the row being
|
||||
// updated while argv[1] is its (possibly changed) new rowid.
|
||||
// updated while argv[1] is its new rowid. VTabUpdater has no
|
||||
// way to convey a rowid change, so reject it instead of
|
||||
// silently updating values under the old rowid.
|
||||
if vals[0] != vals[1] {
|
||||
err = fmt.Errorf("virtual %s table %sdoes not support changing the rowid", vt.module.name, tname)
|
||||
} else {
|
||||
err = v.Update(vals[0], vals[2:])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return mPrintf("%s", err.Error())
|
||||
|
||||
@@ -280,6 +280,19 @@ func TestVUpdate(t *testing.T) {
|
||||
t.Fatalf("expected table vt entry 1 to be [117 f e], instead: %v", vt.data[1])
|
||||
}
|
||||
|
||||
// a rowid-changing update cannot be expressed via VTabUpdater and
|
||||
// must be rejected instead of updating the wrong row
|
||||
_, err = db.Exec(`update vt set rowid = rowid + 10 where f1 = 117`)
|
||||
if err == nil {
|
||||
t.Fatalf("expected error on rowid-changing update, got nil")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "does not support changing the rowid") {
|
||||
t.Fatalf("unexpected error on rowid-changing update: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(vt.data[1], []any{int64(117), "f", "e"}) {
|
||||
t.Fatalf("expected table vt entry 1 to be unchanged, instead: %v", vt.data[1])
|
||||
}
|
||||
|
||||
// delete from vt
|
||||
res, err = db.Exec(`delete from vt where f1 = 117`)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user