Inserts a new `index` into the table. The index will be populated using the rows of the table. # Panics Panics if any row would violate `index`'s unique constraint, if it has one. # Safety Caller must promise that `index` was constructed with the same row type/layout as this table.
(
&mut self,
blob_store: &dyn BlobStore,
index_id: IndexId,
mut index: TableIndex,
)
| 1441 | /// |
| 1442 | /// Caller must promise that `index` was constructed with the same row type/layout as this table. |
| 1443 | pub unsafe fn insert_index( |
| 1444 | &mut self, |
| 1445 | blob_store: &dyn BlobStore, |
| 1446 | index_id: IndexId, |
| 1447 | mut index: TableIndex, |
| 1448 | ) -> Result<(), String> { |
| 1449 | let rows = self.scan_rows(blob_store); |
| 1450 | // SAFETY: Caller promised that table's row type/layout |
| 1451 | // matches that which `index` was constructed with. |
| 1452 | // It follows that this applies to any `rows`, as required. |
| 1453 | let violation = unsafe { index.build_from_rows(rows) }; |
| 1454 | violation.map_err(|ptr| { |
| 1455 | // SAFETY: `ptr` just came out of `self.scan_rows`, so it is present. |
| 1456 | let row = unsafe { self.get_row_ref_unchecked(blob_store, ptr) }.to_product_value(); |
| 1457 | |
| 1458 | if let Some(index_schema) = self.schema.indexes.iter().find(|index_schema| index_schema.index_id == index_id) { |
| 1459 | let cols = index_schema.index_algorithm.columns().to_owned(); |
| 1460 | let cols_infos = cols |
| 1461 | .iter() |
| 1462 | .map(|col| |
| 1463 | self.schema.get_column(col.idx()) |
| 1464 | .map(|c| format!("`{}`", &*c.col_name)) |
| 1465 | .unwrap_or_else(|| "<unknown>".into()) |
| 1466 | ) |
| 1467 | .join(","); |
| 1468 | |
| 1469 | format!( |
| 1470 | "Adding index `{}` {:?} to table `{}` {:?} on columns `{}` {:?} should cause no unique constraint violations.\ |
| 1471 | Found violation at pointer {ptr:?} to row {:?}.", |
| 1472 | index_schema.index_name, |
| 1473 | index_schema.index_id, |
| 1474 | self.schema.table_name, |
| 1475 | self.schema.table_id, |
| 1476 | cols_infos, |
| 1477 | cols, |
| 1478 | row, |
| 1479 | ) |
| 1480 | } else { |
| 1481 | format!( |
| 1482 | "Adding index to table `{}` {:?} on columns `{:?}` with key type {:?} should cause no unique constraint violations.\ |
| 1483 | Found violation at pointer {ptr:?} to row {:?}.", |
| 1484 | self.schema.table_name, |
| 1485 | self.schema.table_id, |
| 1486 | index.indexed_columns(), |
| 1487 | index.key_type(), |
| 1488 | row, |
| 1489 | ) |
| 1490 | } |
| 1491 | })?; |
| 1492 | |
| 1493 | // SAFETY: Forward caller requirement. |
| 1494 | unsafe { self.add_index(index_id, index) }; |
| 1495 | Ok(()) |
| 1496 | } |
| 1497 | |
| 1498 | /// Adds an index to the table without populating. |
| 1499 | /// |