mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-04 18:18:03 +00:00
altered constraint tests to create bad update statements. Tests caught a bug where I was copying the wrong values from the registers
This commit is contained in:
parent
cf7f60b8f5
commit
3aaf4206b7
3 changed files with 58 additions and 13 deletions
|
@ -775,12 +775,13 @@ fn emit_update_insns(
|
|||
let rowid_reg = beg;
|
||||
let idx_cols_start_reg = beg + 1;
|
||||
|
||||
|
||||
// copy each index column from the table's column registers into these scratch regs
|
||||
for i in 0..num_cols {
|
||||
for (i, col) in index.columns.iter().enumerate(){
|
||||
// copy from the table's column register over to the index's scratch register
|
||||
|
||||
program.emit_insn(Insn::Copy {
|
||||
src_reg: idx_cols_start_reg + i,
|
||||
src_reg: idx_cols_start_reg + col.pos_in_table,
|
||||
dst_reg: idx_start_reg + i,
|
||||
amount: 0,
|
||||
});
|
||||
|
|
|
@ -1086,15 +1086,22 @@ pub fn insn_to_str(
|
|||
target_pc,
|
||||
record_reg,
|
||||
num_regs,
|
||||
} => (
|
||||
"NoConflict",
|
||||
*cursor_id as i32,
|
||||
target_pc.to_debug_int(),
|
||||
*record_reg as i32,
|
||||
OwnedValue::build_text(&format!("{num_regs}")),
|
||||
0,
|
||||
format!("key=r[{}]", record_reg),
|
||||
),
|
||||
} => {
|
||||
let key = if *num_regs > 0 {
|
||||
format!("key=r[{}..{}]", record_reg, record_reg + num_regs - 1)
|
||||
} else {
|
||||
format!("key=r[{}]", record_reg)
|
||||
};
|
||||
(
|
||||
"NoConflict",
|
||||
*cursor_id as i32,
|
||||
target_pc.to_debug_int(),
|
||||
*record_reg as i32,
|
||||
OwnedValue::build_text(&format!("{num_regs}")),
|
||||
0,
|
||||
key,
|
||||
)
|
||||
}
|
||||
Insn::NotExists {
|
||||
cursor,
|
||||
rowid_reg,
|
||||
|
|
|
@ -230,12 +230,24 @@ class Table(BaseModel):
|
|||
|
||||
return f"INSERT INTO {self.name} VALUES ({vals});"
|
||||
|
||||
# These statements should always cause a constraint error as there is no where clause here
|
||||
def generate_update(self) -> str:
|
||||
vals = [
|
||||
f"{col.name} = {col.col_type.generate(fake)}"
|
||||
for col in self.columns
|
||||
if col.primary_key
|
||||
]
|
||||
vals = ", ".join(vals)
|
||||
|
||||
return f"UPDATE {self.name} SET {vals};"
|
||||
|
||||
|
||||
class ConstraintTest(BaseModel):
|
||||
table: Table
|
||||
db_path: str = "testing/constraint.db"
|
||||
insert_stmts: list[str]
|
||||
insert_errors: list[str]
|
||||
update_errors: list[str]
|
||||
|
||||
def run(
|
||||
self,
|
||||
|
@ -258,6 +270,14 @@ class ConstraintTest(BaseModel):
|
|||
str(len(self.insert_stmts)),
|
||||
)
|
||||
|
||||
for update_stmt in self.update_errors:
|
||||
limbo.run_test_fn(
|
||||
update_stmt,
|
||||
lambda val: "Runtime error: UNIQUE constraint failed" in val,
|
||||
)
|
||||
|
||||
# TODO: When we implement rollbacks, have a test here to assure the values did not change
|
||||
|
||||
|
||||
def validate_with_expected(result: str, expected: str):
|
||||
return (expected in result, expected)
|
||||
|
@ -281,8 +301,18 @@ def generate_test(col_amount: int, primary_keys: int) -> ConstraintTest:
|
|||
|
||||
table = Table(columns=cols, name=fake.word())
|
||||
insert_stmts = [table.generate_insert() for _ in range(col_amount)]
|
||||
|
||||
update_errors = []
|
||||
if len(insert_stmts) > 1:
|
||||
update_errors = [
|
||||
table.generate_update() for _ in table.columns if col.primary_key
|
||||
]
|
||||
|
||||
return ConstraintTest(
|
||||
table=table, insert_stmts=insert_stmts, insert_errors=insert_stmts
|
||||
table=table,
|
||||
insert_stmts=insert_stmts,
|
||||
insert_errors=insert_stmts,
|
||||
update_errors=update_errors,
|
||||
)
|
||||
|
||||
|
||||
|
@ -296,8 +326,15 @@ def custom_test_1() -> ConstraintTest:
|
|||
"INSERT INTO users VALUES (1, 'alice');",
|
||||
"INSERT INTO users VALUES (2, 'bob');",
|
||||
]
|
||||
update_stmts = [
|
||||
"UPDATE users SET id = 3;",
|
||||
"UPDATE users SET id = 2, username = 'bob' WHERE id == 1;",
|
||||
]
|
||||
return ConstraintTest(
|
||||
table=table, insert_stmts=insert_stmts, insert_errors=insert_stmts
|
||||
table=table,
|
||||
insert_stmts=insert_stmts,
|
||||
insert_errors=insert_stmts,
|
||||
update_errors=update_stmts,
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue