diff --git a/crates/core/src/view_admin.rs b/crates/core/src/view_admin.rs index 2d1c483..c6e2b24 100644 --- a/crates/core/src/view_admin.rs +++ b/crates/core/src/view_admin.rs @@ -122,6 +122,11 @@ DELETE FROM {table};", } if let Some(schema) = state.view_schema() { + // Pretend to be in a sync_local step when clearing raw tables. Similar to the case above + // where we delete from the underlying table to sidestep the CRUD trigger, we don't want + // triggers on raw tables to record this delete in ps_crud. + let _skip_crud = state.sync_local_guard(); + for raw_table in &schema.raw_tables { if let Some(stmt) = &raw_table.clear { local_db.exec_safe(&stmt).map_err(|e| { diff --git a/dart/test/crud_test.dart b/dart/test/crud_test.dart index faea8a7..49dc43a 100644 --- a/dart/test/crud_test.dart +++ b/dart/test/crud_test.dart @@ -946,6 +946,26 @@ void main() { db.execute('UPDATE users SET name = ?', ['name']); expect(db.select('SELECT * FROM ps_crud'), hasLength(1)); }); + + test('clearing raw tables does not create crud entries', () { + db.execute('CREATE TABLE users (id TEXT, name TEXT) STRICT;'); + db.execute( + 'INSERT INTO users (id, name) VALUES (uuid(), ?)', ['test user']); + + createRawTableTriggers(rawTableDescription( + {'table_name': 'users', 'ignore_empty_update': true})); + db.execute('select powersync_replace_schema(?)', [ + json.encode({ + 'tables': [], + 'raw_tables': [ + rawTableDescription({'clear': 'DELETE FROM users'}) + ] + }) + ]); + + db.execute('SELECT powersync_clear(2)'); + expect(db.select('SELECT * FROM ps_crud'), isEmpty); + }); }); }); }