()
| 2479 | |
| 2480 | #[test] |
| 2481 | fn unique_violation_error() { |
| 2482 | let table_name = "UniqueIndexed"; |
| 2483 | let index_name = "UniqueIndexed_unique_col_idx_btree"; |
| 2484 | let mut builder = RawModuleDefV9Builder::new(); |
| 2485 | builder |
| 2486 | .build_table_with_new_type( |
| 2487 | table_name, |
| 2488 | ProductType::from([("unique_col", AlgebraicType::I32), ("other_col", AlgebraicType::I32)]), |
| 2489 | true, |
| 2490 | ) |
| 2491 | .with_unique_constraint(0) |
| 2492 | .with_index(btree(0), "accessor_name_doesnt_matter"); |
| 2493 | |
| 2494 | let def: ModuleDef = builder.finish().try_into().expect("Failed to build schema"); |
| 2495 | |
| 2496 | let schema = TableSchema::from_module_def(&def, def.table(table_name).unwrap(), (), TableId::SENTINEL); |
| 2497 | assert_eq!(schema.indexes.len(), 1); |
| 2498 | let index_schema = schema.indexes[0].clone(); |
| 2499 | |
| 2500 | let mut table = Table::new(schema.into(), SquashedOffset::COMMITTED_STATE); |
| 2501 | let pool = PagePool::new_for_test(); |
| 2502 | let cols = ColList::new(0.into()); |
| 2503 | let algo = BTreeAlgorithm { columns: cols.clone() }.into(); |
| 2504 | |
| 2505 | let index = table.new_index(&algo, true).unwrap(); |
| 2506 | // SAFETY: Index was derived from `table`. |
| 2507 | unsafe { table.insert_index(&NullBlobStore, index_schema.index_id, index) }.unwrap(); |
| 2508 | |
| 2509 | // Reserve a page so that we can check the hash. |
| 2510 | let pi = table.inner.pages.reserve_empty_page(&pool, table.row_size()).unwrap(); |
| 2511 | let hash_pre_ins = hash_unmodified_save_get(&mut table.inner.pages[pi]); |
| 2512 | |
| 2513 | // Insert the row (0, 0). |
| 2514 | table |
| 2515 | .insert(&pool, &mut NullBlobStore, &product![0i32, 0i32]) |
| 2516 | .expect("Initial insert failed"); |
| 2517 | |
| 2518 | // Inserting cleared the hash. |
| 2519 | let hash_post_ins = hash_unmodified_save_get(&mut table.inner.pages[pi]); |
| 2520 | assert_ne!(hash_pre_ins, hash_post_ins); |
| 2521 | |
| 2522 | // Try to insert the row (0, 1), and assert that we get the expected error. |
| 2523 | match table.insert(&pool, &mut NullBlobStore, &product![0i32, 1i32]) { |
| 2524 | Ok(_) => panic!("Second insert with same unique value succeeded"), |
| 2525 | Err(InsertError::IndexError(UniqueConstraintViolation { |
| 2526 | constraint_name, |
| 2527 | table_name, |
| 2528 | cols, |
| 2529 | value, |
| 2530 | })) => { |
| 2531 | assert_eq!(&*constraint_name, index_name); |
| 2532 | assert_eq!(&*table_name, "UniqueIndexed"); |
| 2533 | assert_eq!(cols.iter().map(|c| c.to_string()).collect::<Vec<_>>(), &["unique_col"]); |
| 2534 | assert_eq!(value, AlgebraicValue::I32(0)); |
| 2535 | } |
| 2536 | Err(e) => panic!("Expected UniqueConstraintViolation but found {e:?}"), |
| 2537 | } |
| 2538 |
nothing calls this directly
no test coverage detected
searching dependent graphs…