reifydb_core/
partition.rs1use reifydb_value::{
5 error::{Diagnostic, Error, IntoDiagnostic},
6 fragment::Fragment,
7};
8
9use crate::interface::catalog::{column::Column, object::ObjectId};
10
11pub fn partition_col_indices(columns: &[Column], partition_by: &[String]) -> Vec<usize> {
12 partition_by
13 .iter()
14 .map(|pb| {
15 columns.iter()
16 .position(|c| c.name == *pb)
17 .expect("partition column must exist (validated during planning)")
18 })
19 .collect()
20}
21
22#[derive(Debug, thiserror::Error)]
23pub enum PartitionError {
24 #[error("cannot change partition column via UPDATE on object {object}: partition columns are immutable")]
25 ImmutablePartitionColumn {
26 object: ObjectId,
27 },
28
29 #[error(
30 "partition hash collision on object {object}: hash {hash:032x} maps to two distinct partition value tuples"
31 )]
32 PartitionHashCollision {
33 object: ObjectId,
34 hash: u128,
35 },
36}
37
38impl IntoDiagnostic for PartitionError {
39 fn into_diagnostic(self) -> Diagnostic {
40 match self {
41 PartitionError::ImmutablePartitionColumn {
42 object,
43 } => Diagnostic {
44 code: "PART_002".to_string(),
45 rql: None,
46 message: format!(
47 "cannot change partition column via UPDATE on object {}: partition columns are immutable",
48 object
49 ),
50 column: None,
51 fragment: Fragment::None,
52 label: Some("partition column change rejected".to_string()),
53 help: Some(
54 "partition columns determine a row's physical location and cannot be updated; delete and re-insert the row instead"
55 .to_string(),
56 ),
57 notes: vec![],
58 cause: None,
59 operator_chain: None,
60 },
61
62 PartitionError::PartitionHashCollision {
63 object,
64 hash,
65 } => Diagnostic {
66 code: "PART_003".to_string(),
67 rql: None,
68 message: format!(
69 "partition hash collision on object {}: hash {:032x} maps to two distinct partition value tuples",
70 object, hash
71 ),
72 column: None,
73 fragment: Fragment::None,
74 label: Some("128-bit hash collision".to_string()),
75 help: Some(
76 "two distinct partition value tuples produced the same 128-bit hash; this is astronomically unlikely and points to a hashing bug or data corruption, report it as a bug"
77 .to_string(),
78 ),
79 notes: vec![],
80 cause: None,
81 operator_chain: None,
82 },
83 }
84 }
85}
86
87impl From<PartitionError> for Error {
88 fn from(err: PartitionError) -> Self {
89 Error(Box::new(err.into_diagnostic()))
90 }
91}