1#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum ColumnarError {
9 #[error("codec error: {0}")]
10 Codec(#[from] nodedb_codec::CodecError),
11
12 #[error("segment too short: expected at least {expected} bytes, got {got}")]
13 TruncatedSegment { expected: usize, got: usize },
14
15 #[error("invalid magic bytes: expected NDBS, got {0:?}")]
16 InvalidMagic([u8; 4]),
17
18 #[error(
19 "incompatible segment version: reader {reader_major}.x, segment {segment_major}.{segment_minor}"
20 )]
21 IncompatibleVersion {
22 reader_major: u8,
23 segment_major: u8,
24 segment_minor: u8,
25 },
26
27 #[error("footer CRC32C mismatch: stored {stored:#010x}, computed {computed:#010x}")]
28 FooterCrcMismatch { stored: u32, computed: u32 },
29
30 #[error("column index {index} out of range (segment has {count} columns)")]
31 ColumnOutOfRange { index: usize, count: usize },
32
33 #[error("schema mismatch: expected {expected} columns, memtable has {got}")]
34 SchemaMismatch { expected: usize, got: usize },
35
36 #[error("memtable is empty — nothing to flush")]
37 EmptyMemtable,
38
39 #[error("serialization error: {0}")]
40 Serialization(String),
41
42 #[error("value type mismatch for column '{column}': expected {expected}")]
43 TypeMismatch { column: String, expected: String },
44
45 #[error("JSON parse error for column '{column}': {source}")]
46 JsonParse {
47 column: String,
48 source: sonic_rs::Error,
49 },
50
51 #[error("range literal parse error for column '{column}': invalid range literal '{literal}'")]
52 RangeParse { column: String, literal: String },
53
54 #[error("MessagePack serialization error for column '{column}': {source}")]
55 MsgpackSerialize {
56 column: String,
57 source: zerompk::Error,
58 },
59
60 #[error("MessagePack deserialization error for column '{column}': {source}")]
61 MsgpackDeserialize {
62 column: String,
63 source: nodedb_types::MsgpackError,
64 },
65
66 #[error("null violation: column '{0}' is NOT NULL")]
67 NullViolation(String),
68
69 #[error("duplicate primary key")]
70 DuplicatePrimaryKey,
71
72 #[error("primary key not found")]
73 PrimaryKeyNotFound,
74
75 #[error("segment ID space exhausted: u64::MAX segments have been allocated")]
76 SegmentIdExhausted,
77
78 #[error("segment corruption in {segment_id:?} at offset {offset:?}: {reason}")]
84 Corruption {
85 segment_id: Option<String>,
86 reason: String,
87 offset: Option<u64>,
88 },
89
90 #[error("memtable cell corrupt: column '{column}' row {row}: {reason}")]
95 MemtableCellCorrupt {
96 column: String,
97 row: usize,
98 reason: String,
99 },
100
101 #[error("columnar WAL row corrupt at byte {offset}: {reason}")]
107 WalRowCorrupt { offset: usize, reason: String },
108
109 #[error("string column '{column}' row {row} holds bytes that are not UTF-8")]
115 StringCellNotUtf8 { column: String, row: usize },
116
117 #[error(
119 "columnar segment is encrypted but no encryption key was provided; \
120 cannot read an encrypted segment without a key"
121 )]
122 MissingKek,
123
124 #[error(
126 "columnar segment is plaintext but an encryption key is configured; \
127 refusing to load an unencrypted segment when encryption is required"
128 )]
129 KekRequired,
130
131 #[error("columnar segment encryption failed: {0}")]
133 EncryptionFailed(String),
134
135 #[error("columnar segment decryption failed: {0}")]
137 DecryptionFailed(String),
138
139 #[error("memory budget exhausted: {0}")]
141 BudgetExhausted(#[from] nodedb_mem::MemError),
142}