diff --git a/tests/integration/functions/test_cdc.rs b/tests/integration/functions/test_cdc.rs index bae90808f..f2842b74e 100644 --- a/tests/integration/functions/test_cdc.rs +++ b/tests/integration/functions/test_cdc.rs @@ -879,3 +879,205 @@ fn test_cdc_bin_record() { )]] ); } + +#[test] +fn test_cdc_schema_changes() { + let db = TempDatabase::new_empty(true); + let conn = db.connect_limbo(); + conn.execute("PRAGMA unstable_capture_data_changes_conn('full')") + .unwrap(); + conn.execute("CREATE TABLE t(x, y, z UNIQUE, q, PRIMARY KEY (x, y))") + .unwrap(); + conn.execute("CREATE TABLE q(a, b, c)").unwrap(); + conn.execute("CREATE INDEX t_q ON t(q)").unwrap(); + conn.execute("CREATE INDEX q_abc ON q(a, b, c)").unwrap(); + conn.execute("DROP TABLE t").unwrap(); + conn.execute("DROP INDEX q_abc").unwrap(); + let rows = replace_column_with_null(limbo_exec_rows(&db, &conn, "SELECT * FROM turso_cdc"), 1); + + assert_eq!( + rows, + vec![ + vec![ + Value::Integer(1), + Value::Null, + Value::Integer(1), + Value::Text("sqlite_schema".to_string()), + Value::Integer(2), + Value::Null, + Value::Blob(record([ + Value::Text("table".to_string()), + Value::Text("t".to_string()), + Value::Text("t".to_string()), + Value::Integer(3), + Value::Text( + "CREATE TABLE t (x, y, z UNIQUE, q, PRIMARY KEY (x, y))".to_string() + ) + ])), + ], + vec![ + Value::Integer(2), + Value::Null, + Value::Integer(1), + Value::Text("sqlite_schema".to_string()), + Value::Integer(5), + Value::Null, + Value::Blob(record([ + Value::Text("table".to_string()), + Value::Text("q".to_string()), + Value::Text("q".to_string()), + Value::Integer(6), + Value::Text("CREATE TABLE q (a, b, c)".to_string()) + ])), + ], + vec![ + Value::Integer(3), + Value::Null, + Value::Integer(1), + Value::Text("sqlite_schema".to_string()), + Value::Integer(6), + Value::Null, + Value::Blob(record([ + Value::Text("index".to_string()), + Value::Text("t_q".to_string()), + Value::Text("t".to_string()), + Value::Integer(7), + Value::Text("CREATE INDEX t_q ON t (q)".to_string()) + ])), + ], + vec![ + Value::Integer(4), + Value::Null, + Value::Integer(1), + Value::Text("sqlite_schema".to_string()), + Value::Integer(7), + Value::Null, + Value::Blob(record([ + Value::Text("index".to_string()), + Value::Text("q_abc".to_string()), + Value::Text("q".to_string()), + Value::Integer(8), + Value::Text("CREATE INDEX q_abc ON q (a, b, c)".to_string()) + ])), + ], + vec![ + Value::Integer(5), + Value::Null, + Value::Integer(-1), + Value::Text("sqlite_schema".to_string()), + Value::Integer(2), + Value::Blob(record([ + Value::Text("table".to_string()), + Value::Text("t".to_string()), + Value::Text("t".to_string()), + Value::Integer(3), + Value::Text( + "CREATE TABLE t (x, y, z UNIQUE, q, PRIMARY KEY (x, y))".to_string() + ) + ])), + Value::Null, + ], + vec![ + Value::Integer(6), + Value::Null, + Value::Integer(-1), + Value::Text("sqlite_schema".to_string()), + Value::Integer(7), + Value::Blob(record([ + Value::Text("index".to_string()), + Value::Text("q_abc".to_string()), + Value::Text("q".to_string()), + Value::Integer(8), + Value::Text("CREATE INDEX q_abc ON q (a, b, c)".to_string()) + ])), + Value::Null, + ] + ] + ); +} + +#[test] +fn test_cdc_schema_changes_alter_table() { + let db = TempDatabase::new_empty(true); + let conn = db.connect_limbo(); + conn.execute("PRAGMA unstable_capture_data_changes_conn('full')") + .unwrap(); + conn.execute("CREATE TABLE t(x, y, z UNIQUE, q, PRIMARY KEY (x, y))") + .unwrap(); + conn.execute("ALTER TABLE t DROP COLUMN q").unwrap(); + conn.execute("ALTER TABLE t ADD COLUMN t").unwrap(); + let rows = replace_column_with_null(limbo_exec_rows(&db, &conn, "SELECT * FROM turso_cdc"), 1); + + assert_eq!( + rows, + vec![ + vec![ + Value::Integer(1), + Value::Null, + Value::Integer(1), + Value::Text("sqlite_schema".to_string()), + Value::Integer(2), + Value::Null, + Value::Blob(record([ + Value::Text("table".to_string()), + Value::Text("t".to_string()), + Value::Text("t".to_string()), + Value::Integer(3), + Value::Text( + "CREATE TABLE t (x, y, z UNIQUE, q, PRIMARY KEY (x, y))".to_string() + ) + ])), + ], + vec![ + Value::Integer(2), + Value::Null, + Value::Integer(0), + Value::Text("sqlite_schema".to_string()), + Value::Integer(2), + Value::Blob(record([ + Value::Text("table".to_string()), + Value::Text("t".to_string()), + Value::Text("t".to_string()), + Value::Integer(3), + Value::Text( + "CREATE TABLE t (x, y, z UNIQUE, q, PRIMARY KEY (x, y))".to_string() + ) + ])), + Value::Blob(record([ + Value::Text("table".to_string()), + Value::Text("t".to_string()), + Value::Text("t".to_string()), + Value::Integer(3), + Value::Text( + "CREATE TABLE t (x PRIMARY KEY, y PRIMARY KEY, z UNIQUE)".to_string() + ) + ])), + ], + vec![ + Value::Integer(3), + Value::Null, + Value::Integer(0), + Value::Text("sqlite_schema".to_string()), + Value::Integer(2), + Value::Blob(record([ + Value::Text("table".to_string()), + Value::Text("t".to_string()), + Value::Text("t".to_string()), + Value::Integer(3), + Value::Text( + "CREATE TABLE t (x PRIMARY KEY, y PRIMARY KEY, z UNIQUE)".to_string() + ) + ])), + Value::Blob(record([ + Value::Text("table".to_string()), + Value::Text("t".to_string()), + Value::Text("t".to_string()), + Value::Integer(3), + Value::Text( + "CREATE TABLE t (x PRIMARY KEY, y PRIMARY KEY, z UNIQUE, t)".to_string() + ) + ])), + ], + ] + ); +}