1use pest::iterators::Pair;
2use substrait::proto::r#type::{Kind, Nullability, Parameter};
3use substrait::proto::{self, Type};
4
5use super::{ParsePair, Rule, ScopedParsePair, iter_pairs, unwrap_single_pair};
6use crate::extensions::SimpleExtensions;
7use crate::extensions::simple::{ExtensionKind, MissingReference};
8use crate::parser::MessageParseError;
9
10pub(crate) fn get_and_validate_anchor(
18 extensions: &SimpleExtensions,
19 kind: ExtensionKind,
20 anchor: Option<u32>,
21 name: &str,
22 span: pest::Span,
23) -> Result<u32, MessageParseError> {
24 if kind == ExtensionKind::Function {
25 return extensions
26 .resolve_function(name, anchor)
27 .map(|r| r.anchor)
28 .map_err(|e| {
29 MessageParseError::lookup(kind.name(), e, span, "Error resolving function")
30 });
31 }
32 match anchor {
34 Some(a) => match extensions.find_by_anchor(kind, a) {
35 Err(e) => Err(MessageParseError::lookup(
36 kind.name(),
37 e,
38 span,
39 "Error matching name to anchor",
40 )),
41 Ok((_, stored)) => {
42 if stored.full() == name || stored.base() == name {
43 Ok(a)
44 } else {
45 Err(MessageParseError::lookup(
46 kind.name(),
47 MissingReference::Mismatched(kind, name.to_string(), a),
48 span,
49 "Error matching name to anchor",
50 ))
51 }
52 }
53 },
54 None => extensions.find_by_name(kind, name).map_err(|e| {
55 MessageParseError::lookup(kind.name(), e, span, "Error finding extension for name")
56 }),
57 }
58}
59
60impl ParsePair for Nullability {
61 fn rule() -> Rule {
62 Rule::nullability
63 }
64
65 fn message() -> &'static str {
66 "Nullability"
67 }
68
69 fn parse_pair(pair: Pair<Rule>) -> Self {
70 assert_eq!(pair.as_rule(), Rule::nullability);
71 match pair.as_str() {
72 "?" => Nullability::Nullable,
73 "" => Nullability::Required,
74 "⁉" => Nullability::Unspecified,
75 _ => panic!("Invalid nullability: {}", pair.as_str()),
76 }
77 }
78}
79
80impl ScopedParsePair for Parameter {
81 fn rule() -> Rule {
82 Rule::parameter
83 }
84
85 fn message() -> &'static str {
86 "Parameter"
87 }
88
89 fn parse_pair(
90 extensions: &SimpleExtensions,
91 pair: Pair<Rule>,
92 ) -> Result<Self, MessageParseError> {
93 assert_eq!(pair.as_rule(), Rule::parameter);
94 let inner = unwrap_single_pair(pair);
95 match inner.as_rule() {
96 Rule::r#type => Ok(Parameter {
97 parameter: Some(proto::r#type::parameter::Parameter::DataType(
98 Type::parse_pair(extensions, inner)?,
99 )),
100 }),
101 _ => unimplemented!("{:?}", inner.as_rule()),
102 }
103 }
104}
105
106fn parse_simple_type(pair: Pair<Rule>) -> Type {
107 assert_eq!(pair.as_rule(), Rule::simple_type);
108 let mut iter = iter_pairs(pair.into_inner());
109 let name = iter.pop(Rule::simple_type_name).as_str();
110 let nullability = iter.parse_next::<Nullability>();
111 iter.done();
112
113 let kind = match name {
114 "boolean" => Kind::Bool(proto::r#type::Boolean {
115 nullability: nullability.into(),
116 type_variation_reference: 0,
117 }),
118 "i64" => Kind::I64(proto::r#type::I64 {
119 nullability: nullability.into(),
120 type_variation_reference: 0,
121 }),
122 "i32" => Kind::I32(proto::r#type::I32 {
123 nullability: nullability.into(),
124 type_variation_reference: 0,
125 }),
126 "i16" => Kind::I16(proto::r#type::I16 {
127 nullability: nullability.into(),
128 type_variation_reference: 0,
129 }),
130 "i8" => Kind::I8(proto::r#type::I8 {
131 nullability: nullability.into(),
132 type_variation_reference: 0,
133 }),
134 "fp32" => Kind::Fp32(proto::r#type::Fp32 {
135 nullability: nullability.into(),
136 type_variation_reference: 0,
137 }),
138 "fp64" => Kind::Fp64(proto::r#type::Fp64 {
139 nullability: nullability.into(),
140 type_variation_reference: 0,
141 }),
142 "string" => Kind::String(proto::r#type::String {
143 nullability: nullability.into(),
144 type_variation_reference: 0,
145 }),
146 "binary" => Kind::Binary(proto::r#type::Binary {
147 nullability: nullability.into(),
148 type_variation_reference: 0,
149 }),
150 #[allow(deprecated)]
151 "timestamp" => Kind::Timestamp(proto::r#type::Timestamp {
152 nullability: nullability.into(),
153 type_variation_reference: 0,
154 }),
155 #[allow(deprecated)]
156 "timestamp_tz" => Kind::TimestampTz(proto::r#type::TimestampTz {
157 nullability: nullability.into(),
158 type_variation_reference: 0,
159 }),
160 "date" => Kind::Date(proto::r#type::Date {
161 nullability: nullability.into(),
162 type_variation_reference: 0,
163 }),
164 #[allow(deprecated)]
165 "time" => Kind::Time(proto::r#type::Time {
166 nullability: nullability.into(),
167 type_variation_reference: 0,
168 }),
169 "interval_year" => Kind::IntervalYear(proto::r#type::IntervalYear {
170 nullability: nullability.into(),
171 type_variation_reference: 0,
172 }),
173 "uuid" => Kind::Uuid(proto::r#type::Uuid {
174 nullability: nullability.into(),
175 type_variation_reference: 0,
176 }),
177 _ => unreachable!("Type {} exists in parser but not implemented in code", name),
178 };
179 Type { kind: Some(kind) }
180}
181
182fn parse_compound_type(
183 extensions: &SimpleExtensions,
184 pair: Pair<Rule>,
185) -> Result<Type, MessageParseError> {
186 assert_eq!(pair.as_rule(), Rule::compound_type);
187 let inner = unwrap_single_pair(pair);
188 match inner.as_rule() {
189 Rule::list_type => parse_list_type(extensions, inner),
190 _ => unimplemented!("{:?}", inner.as_rule()),
193 }
194}
195
196fn parse_list_type(
197 extensions: &SimpleExtensions,
198 pair: Pair<Rule>,
199) -> Result<Type, MessageParseError> {
200 assert_eq!(pair.as_rule(), Rule::list_type);
201 let mut iter = iter_pairs(pair.into_inner());
202 let nullability = iter.parse_next::<Nullability>();
203 let inner = iter.parse_next_scoped::<Type>(extensions)?;
204 iter.done();
205
206 Ok(Type {
207 kind: Some(Kind::List(Box::new(proto::r#type::List {
208 nullability: nullability.into(),
209 r#type: Some(Box::new(inner)),
210 type_variation_reference: 0,
211 }))),
212 })
213}
214
215fn parse_parameters(
216 extensions: &SimpleExtensions,
217 pair: Pair<Rule>,
218) -> Result<Vec<Parameter>, MessageParseError> {
219 assert_eq!(pair.as_rule(), Rule::parameters);
220 let mut iter = iter_pairs(pair.into_inner());
221 let mut params = Vec::new();
222 while let Some(param) = iter.parse_if_next_scoped::<Parameter>(extensions) {
223 params.push(param?);
224 }
225 iter.done();
226 Ok(params)
227}
228
229fn parse_user_defined_type(
230 extensions: &SimpleExtensions,
231 pair: Pair<Rule>,
232) -> Result<Type, MessageParseError> {
233 let span = pair.as_span();
234 assert_eq!(pair.as_rule(), Rule::user_defined_type);
235 let mut iter = iter_pairs(pair.into_inner());
236 let name = iter.pop(Rule::name).as_str();
237 let anchor = iter
238 .try_pop(Rule::anchor)
239 .map(|n| unwrap_single_pair(n).as_str().parse::<u32>().unwrap());
240
241 let _urn_anchor = iter
243 .try_pop(Rule::urn_anchor)
244 .map(|n| unwrap_single_pair(n).as_str().parse::<u32>().unwrap());
245
246 let nullability = iter.parse_next::<Nullability>();
247 let parameters = match iter.try_pop(Rule::parameters) {
248 Some(p) => parse_parameters(extensions, p)?,
249 None => Vec::new(),
250 };
251 iter.done();
252
253 let anchor = get_and_validate_anchor(extensions, ExtensionKind::Type, anchor, name, span)?;
254
255 Ok(Type {
256 kind: Some(Kind::UserDefined(proto::r#type::UserDefined {
257 type_reference: anchor,
258 nullability: nullability.into(),
259 type_parameters: parameters,
260 type_variation_reference: 0,
261 })),
262 })
263}
264
265impl ScopedParsePair for Type {
266 fn rule() -> Rule {
267 Rule::r#type
268 }
269
270 fn message() -> &'static str {
271 "Type"
272 }
273
274 fn parse_pair(
275 extensions: &SimpleExtensions,
276 pair: Pair<Rule>,
277 ) -> Result<Self, MessageParseError> {
278 assert_eq!(pair.as_rule(), Rule::r#type);
279 let inner = unwrap_single_pair(pair);
280 match inner.as_rule() {
281 Rule::simple_type => Ok(parse_simple_type(inner)),
282 Rule::compound_type => parse_compound_type(extensions, inner),
283 Rule::user_defined_type => parse_user_defined_type(extensions, inner),
284 _ => unreachable!(
285 "Grammar guarantees type can only be simple_type, compound_type, or user_defined_type, got: {:?}",
286 inner.as_rule()
287 ),
288 }
289 }
290}
291
292#[cfg(test)]
293mod tests {
294 use pest::Parser;
295 use substrait::proto::r#type::{I64, Kind, Nullability};
296
297 use super::*;
298 use crate::parser::ExpressionParser;
299
300 #[test]
301 fn test_parse_simple_type() {
302 let mut pairs = ExpressionParser::parse(Rule::simple_type, "i64").unwrap();
303 let pair = pairs.next().unwrap();
304 assert_eq!(pairs.next(), None);
305 let t = parse_simple_type(pair);
306 assert_eq!(
307 t,
308 Type {
309 kind: Some(Kind::I64(I64 {
310 nullability: Nullability::Required as i32,
311 type_variation_reference: 0,
312 })),
313 }
314 );
315
316 let mut pairs = ExpressionParser::parse(Rule::simple_type, "string?").unwrap();
317 let pair = pairs.next().unwrap();
318 assert_eq!(pairs.next(), None);
319 let t = parse_simple_type(pair);
320 assert_eq!(
321 t,
322 Type {
323 kind: Some(Kind::String(proto::r#type::String {
324 nullability: Nullability::Nullable as i32,
325 type_variation_reference: 0,
326 })),
327 }
328 );
329 }
330
331 #[test]
332 fn test_parse_type() {
333 let extensions = SimpleExtensions::default();
334 let mut pairs = ExpressionParser::parse(Rule::r#type, "i64").unwrap();
335 let pair = pairs.next().unwrap();
336 assert_eq!(pairs.next(), None);
337 let t = Type::parse_pair(&extensions, pair).unwrap();
338 assert_eq!(
339 t,
340 Type {
341 kind: Some(Kind::I64(I64 {
342 nullability: Nullability::Required as i32,
343 type_variation_reference: 0,
344 }))
345 }
346 );
347 }
348
349 #[test]
350 fn test_parse_list_type() {
351 let extensions = SimpleExtensions::default();
352 let mut pairs = ExpressionParser::parse(Rule::list_type, "list<i64>").unwrap();
353 let pair = pairs.next().unwrap();
354 assert_eq!(pairs.next(), None);
355 let t = parse_list_type(&extensions, pair).unwrap();
356 assert_eq!(
357 t,
358 Type {
359 kind: Some(Kind::List(Box::new(proto::r#type::List {
360 nullability: Nullability::Required as i32,
361 r#type: Some(Box::new(Type {
362 kind: Some(Kind::I64(I64 {
363 nullability: Nullability::Required as i32,
364 type_variation_reference: 0,
365 }))
366 })),
367 type_variation_reference: 0,
368 })))
369 }
370 );
371 }
372
373 #[test]
374 fn test_parse_parameters() {
375 let extensions = SimpleExtensions::default();
376 let mut pairs = ExpressionParser::parse(Rule::parameters, "<i64?,string>").unwrap();
377 let pair = pairs.next().unwrap();
378 assert_eq!(pairs.next(), None);
379 let t = parse_parameters(&extensions, pair).unwrap();
380 assert_eq!(
381 t,
382 vec![
383 Parameter {
384 parameter: Some(proto::r#type::parameter::Parameter::DataType(Type {
385 kind: Some(Kind::I64(proto::r#type::I64 {
386 nullability: Nullability::Nullable as i32,
387 type_variation_reference: 0,
388 })),
389 })),
390 },
391 Parameter {
392 parameter: Some(proto::r#type::parameter::Parameter::DataType(Type {
393 kind: Some(Kind::String(proto::r#type::String {
394 nullability: Nullability::Required as i32,
395 type_variation_reference: 0,
396 })),
397 })),
398 },
399 ]
400 );
401 }
402
403 #[test]
404 fn test_udts() {
405 let mut extensions = SimpleExtensions::default();
406 extensions
407 .add_extension_urn("some_source".to_string(), 4)
408 .unwrap();
409 extensions
410 .add_extension(ExtensionKind::Type, 4, 42, "udt".to_string())
411 .unwrap();
412 let mut pairs = ExpressionParser::parse(Rule::user_defined_type, "udt#42<i64?>").unwrap();
413 let pair = pairs.next().unwrap();
414 assert_eq!(pairs.next(), None);
415
416 let t = parse_user_defined_type(&extensions, pair).unwrap();
417 assert_eq!(
418 t,
419 Type {
420 kind: Some(Kind::UserDefined(proto::r#type::UserDefined {
421 type_reference: 42,
422 type_variation_reference: 0,
423 nullability: Nullability::Required as i32,
424 type_parameters: vec![Parameter {
425 parameter: Some(proto::r#type::parameter::Parameter::DataType(Type {
426 kind: Some(Kind::I64(proto::r#type::I64 {
427 nullability: Nullability::Nullable as i32,
428 type_variation_reference: 0,
429 })),
430 })),
431 }],
432 }))
433 }
434 );
435 }
436}