Skip to main content

densa_data/
error.rs

1use std::fmt;
2
3/// Why a table or view operation was refused. Nothing changes when one is returned.
4#[derive(Debug, Clone, PartialEq, Eq)]
5#[non_exhaustive]
6pub enum DataError {
7    /// No column has this name.
8    UnknownColumn(String),
9    /// The key column must hold integers or strings.
10    UnsupportedKey(String),
11    /// Views and groups cannot read this column's data type (lists, structs, binary, ...).
12    UnsupportedColumn(String),
13    /// A filter's value or operation does not fit this column's type (text compared with a
14    /// number, `contains` on a number).
15    LiteralMismatch(String),
16    /// Sums and means need an integer, decimal or float column; this one holds something
17    /// else (text, booleans, dates, times).
18    NotNumeric(String),
19    /// A window's span does not fit its column: a `Duration` goes with dates, times and
20    /// timestamps, a number (zero or more) with integers, decimals and floats.
21    WindowSpan(String),
22    /// A group's bucket width does not fit its column: a `Duration` of at least one of its
23    /// units goes with dates, times and timestamps, a number of at least one unit with
24    /// integers and decimals, a finite number above zero with floats.
25    BucketWidth(String),
26    /// Two columns of a group spec's result would have this name.
27    DuplicateName(String),
28    /// The batch has a different number of columns.
29    ColumnCount {
30        /// Columns in the table.
31        expected: usize,
32        /// Columns in the batch.
33        found: usize,
34    },
35    /// The batch's column at this index has another name or data type.
36    ColumnMismatch {
37        /// Index of the first differing column.
38        column: usize,
39    },
40    /// A row of the batch has no key.
41    NullKey {
42        /// The row, within the batch.
43        row: usize,
44    },
45    /// Keys to delete or find are not of the key column's kind (text for a number key).
46    KeyType,
47    /// More than 2^32 live keys, or rows in one batch.
48    TooManyRows,
49    /// Arrow could not build a batch: compacting a table, or assembling groups.
50    Arrow(String),
51}
52
53impl fmt::Display for DataError {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        match self {
56            Self::UnknownColumn(name) => write!(
57                f,
58                "there is no column named {name:?}: names match exactly, case included \
59                 (the table's schema lists them)"
60            ),
61            Self::UnsupportedKey(name) => {
62                write!(f, "key column {name:?} must hold integers or strings")
63            }
64            Self::UnsupportedColumn(name) => {
65                write!(
66                    f,
67                    "views and groups cannot read column {name:?} of this type: they read \
68                     booleans, integers, floats, decimals, text (or dictionaries of text), dates, \
69                     times, timestamps and durations"
70                )
71            }
72            Self::LiteralMismatch(name) => {
73                write!(f, "the filter does not fit the type of column {name:?}")
74            }
75            Self::NotNumeric(name) => {
76                write!(
77                    f,
78                    "column {name:?} is not numeric, so it has no sum or mean: those take \
79                     integers, decimals and floats (count takes no column; min and max take any column \
80                     views can sort)"
81                )
82            }
83            Self::WindowSpan(name) => {
84                write!(
85                    f,
86                    "the window's span does not fit the type of column {name:?}: \
87                     Window::duration goes with dates, times, timestamps and durations, \
88                     Window::span (zero or more) with integers, decimals and floats"
89                )
90            }
91            Self::BucketWidth(name) => {
92                write!(
93                    f,
94                    "the bucket width does not fit the type of column {name:?}: \
95                     group_by_time takes at least one of the column's units for dates, times, \
96                     timestamps and durations, group_by_step at least one unit for integers \
97                     and decimals, or a finite step above zero for floats"
98                )
99            }
100            Self::DuplicateName(name) => write!(
101                f,
102                "two result columns are named {name:?}: give an aggregate another name with \
103                 Aggregate::named"
104            ),
105            Self::ColumnCount { expected, found } => {
106                write!(f, "the batch has {found} columns, the table {expected}")
107            }
108            Self::ColumnMismatch { column } => {
109                write!(
110                    f,
111                    "column {column} of the batch has another name or data type than the \
112                     table's: every batch must have the table's schema (LiveTable::schema)"
113                )
114            }
115            Self::NullKey { row } => write!(f, "row {row} of the batch has a null key"),
116            Self::KeyType => f.write_str(
117                "the keys are not of the key column's kind: give integers for a key column of \
118                 integers, strings for one of strings",
119            ),
120            Self::TooManyRows => f.write_str("more than 2^32 live keys, or rows in one batch"),
121            Self::Arrow(message) => write!(f, "Arrow could not build a batch: {message}"),
122        }
123    }
124}
125
126impl std::error::Error for DataError {}
127
128impl DataError {
129    pub(crate) fn arrow(error: arrow_schema::ArrowError) -> Self {
130        Self::Arrow(error.to_string())
131    }
132}