gluesql_core/executor/evaluate/
error.rs1use {
2 crate::ast::{Aggregate, BinaryOperator, DataType, Expr, ToSql},
3 serde::{Serialize, Serializer},
4 std::fmt::Debug,
5 thiserror::Error,
6};
7
8#[derive(Error, Serialize, Debug, PartialEq, Eq)]
9pub enum EvaluateError {
10 #[error(transparent)]
11 #[serde(serialize_with = "error_serialize")]
12 FormatParseError(#[from] chrono::format::ParseError),
13
14 #[error("literal add on non-numeric")]
15 LiteralAddOnNonNumeric,
16
17 #[error("function requires string value: {0}")]
18 FunctionRequiresStringValue(String),
19
20 #[error("function requires integer or string value: {0}")]
21 FunctionRequiresIntegerOrStringValue(String),
22
23 #[error("arrow base requires MAP or LIST types")]
24 ArrowBaseRequiresMapOrList,
25
26 #[error("arrow selector requires integer or string value: {0}")]
27 ArrowSelectorRequiresIntegerOrString(String),
28
29 #[error("function requires integer value: {0}")]
30 FunctionRequiresIntegerValue(String),
31
32 #[error("function requires float or integer value: {0}")]
33 FunctionRequiresFloatOrIntegerValue(String),
34
35 #[error("function requires usize value: {0}")]
36 FunctionRequiresUSizeValue(String),
37
38 #[error("function requires float value: {0}")]
39 FunctionRequiresFloatValue(String),
40
41 #[error("extract format does not support value: {0}")]
42 ExtractFormatNotMatched(String),
43
44 #[error("function requires map value: {0}")]
45 FunctionRequiresMapValue(String),
46
47 #[error("function requires point value: {0}")]
48 FunctionRequiresPointValue(String),
49
50 #[error("function requires date or datetime value: {0}")]
51 FunctionRequiresDateOrDateTimeValue(String),
52
53 #[error("function requires one of string, list, map types: {0}")]
54 FunctionRequiresStrOrListOrMapValue(String),
55
56 #[error("identifier not found: {0}")]
57 IdentifierNotFound(String),
58
59 #[error("identifier not found: {table_alias}.{column_name}")]
60 CompoundIdentifierNotFound {
61 table_alias: String,
62 column_name: String,
63 },
64
65 #[error("only boolean value is accepted: {0}")]
66 BooleanTypeRequired(String),
67
68 #[error("expr requires map or list value")]
69 MapOrListTypeRequired,
70
71 #[error("expr requires map value")]
72 MapTypeRequired,
73
74 #[error("expr requires list value")]
75 ListTypeRequired,
76
77 #[error("all elements in the list must be comparable to each other")]
78 InvalidSortType,
79
80 #[error("sort order must be either ASC or DESC")]
81 InvalidSortOrder,
82
83 #[error("map or string value required for json map conversion: {0}")]
84 MapOrStringValueRequired(String),
85
86 #[error("text literal required for json map conversion: {0}")]
87 TextLiteralRequired(String),
88
89 #[error("unsupported stateless expression: {}", .0.to_sql())]
90 UnsupportedStatelessExpr(Box<Expr>),
91
92 #[error("context is required for identifier evaluation: {}", .0.to_sql())]
93 ContextRequiredForIdentEvaluation(Box<Expr>),
94
95 #[error("unreachable empty aggregate value: {0:?}")]
96 UnreachableEmptyAggregateValue(Box<Aggregate>),
97
98 #[error("filter context is required for aggregate function: {0:?}")]
99 FilterContextRequiredForAggregate(Box<Aggregate>),
100
101 #[error("incompatible bit operation between {0} and {1}")]
102 IncompatibleBitOperation(String, String),
103
104 #[error("the divisor should not be zero")]
105 DivisorShouldNotBeZero,
106
107 #[error("negative substring length not allowed")]
108 NegativeSubstrLenNotAllowed,
109
110 #[error("subquery returns more than one row")]
111 MoreThanOneRowReturned,
112
113 #[error("subquery returns more than one column")]
114 MoreThanOneColumnReturned,
115
116 #[error("schemaless projection is not allowed for IN (subquery)")]
117 SchemalessProjectionForInSubQuery,
118
119 #[error("schemaless projection is not allowed for subquery")]
120 SchemalessProjectionForSubQuery,
121
122 #[error("format function does not support following data_type: {0}")]
123 UnsupportedExprForFormatFunction(String),
124
125 #[error("support single character only")]
126 AsciiFunctionRequiresSingleCharacterValue,
127
128 #[error("non-ascii character not allowed")]
129 NonAsciiCharacterNotAllowed,
130
131 #[error("function requires integer value in range")]
132 ChrFunctionRequiresIntegerValueInRange0To255,
133
134 #[error("unsupported evaluate binary operation {} {} {}", .left, .op.to_sql(), .right)]
135 UnsupportedBinaryOperation {
136 left: String,
137 op: BinaryOperator,
138 right: String,
139 },
140
141 #[error("unsupported evaluate string unary plus: {0}")]
142 UnsupportedUnaryPlus(String),
143
144 #[error("unsupported evaluate string unary minus: {0}")]
145 UnsupportedUnaryMinus(String),
146
147 #[error("unary factorial requires numeric literal: {0}")]
148 UnaryFactorialRequiresNumericLiteral(String),
149
150 #[error("unary bitwise-not requires integer literal: {0}")]
151 UnaryBitwiseNotRequiresIntegerLiteral(String),
152
153 #[error("operator doesn't exist: {base} {case} {pattern}", case = if *case_sensitive { "LIKE" } else { "ILIKE" })]
154 LikeOnNonStringLiteral {
155 base: String,
156 pattern: String,
157 case_sensitive: bool,
158 },
159
160 #[error("unsupported custom function in subqueries")]
161 UnsupportedCustomFunction,
162
163 #[error(r#"The function "{function_name}" requires at least {required_minimum} argument(s), but {found} were provided."#)]
164 FunctionRequiresMoreArguments {
165 function_name: String,
166 required_minimum: usize,
167 found: usize,
168 },
169
170 #[error(
171 "function args.length not matching: {name}, expected: {expected_minimum} ~ {expected_maximum}, found: {found}"
172 )]
173 FunctionArgsLengthNotWithinRange {
174 name: String,
175 expected_minimum: usize,
176 expected_maximum: usize,
177 found: usize,
178 },
179
180 #[error("unsupported function: {0}")]
181 UnsupportedFunction(String),
182
183 #[error("The provided arguments are non-comparable: {0}")]
184 NonComparableArgumentError(String),
185
186 #[error("function requires at least one argument: {0}")]
187 FunctionRequiresAtLeastOneArgument(String),
188
189 #[error("function CONCAT requires at least 1 argument")]
190 EmptyArgNotAllowedInConcat,
191
192 #[error("LCM calculation resulted in a value out of the i64 range")]
193 LcmResultOutOfRange,
194
195 #[error("GCD or LCM calculation overflowed on trying to get the absolute value of {0}")]
196 GcdLcmOverflow(i64),
197
198 #[error("failed to convert Value to u32: {0}")]
199 I64ToU32ConversionFailure(String),
200
201 #[error("failed to parse number {literal:?} to {data_type}")]
202 NumberParseFailed {
203 literal: String,
204 data_type: DataType,
205 },
206
207 #[error("failed to cast number {literal:?} to {data_type}")]
208 NumberCastFailed {
209 literal: String,
210 data_type: DataType,
211 },
212
213 #[error("failed to parse text {literal:?} to {data_type}")]
214 TextParseFailed {
215 literal: String,
216 data_type: DataType,
217 },
218
219 #[error("failed to cast text {literal:?} to {data_type}")]
220 TextCastFailed {
221 literal: String,
222 data_type: DataType,
223 },
224}
225
226#[allow(clippy::trivially_copy_pass_by_ref)]
227fn error_serialize<S>(error: &chrono::format::ParseError, serializer: S) -> Result<S::Ok, S::Error>
228where
229 S: Serializer,
230{
231 let display = format!("{error}");
232 serializer.serialize_str(&display)
233}