datafusion-distributed 1.0.0

Framework for enhancing Apache DataFusion with distributed capabilities
Documentation
use datafusion::sql::sqlparser::parser::ParserError;

#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ParserErrorProto {
    #[prost(oneof = "ParserErrorInnerProto", tags = "1,2,3")]
    pub inner: Option<ParserErrorInnerProto>,
}

#[derive(Clone, PartialEq, prost::Oneof)]
pub enum ParserErrorInnerProto {
    #[prost(string, tag = "1")]
    TokenizerError(String),
    #[prost(string, tag = "2")]
    ParserError(String),
    #[prost(bool, tag = "3")]
    RecursionLimitExceeded(bool),
}

impl ParserErrorProto {
    pub fn from_parser_error(err: &ParserError) -> Self {
        match err {
            ParserError::TokenizerError(msg) => ParserErrorProto {
                inner: Some(ParserErrorInnerProto::TokenizerError(msg.to_string())),
            },
            ParserError::ParserError(msg) => ParserErrorProto {
                inner: Some(ParserErrorInnerProto::ParserError(msg.to_string())),
            },
            ParserError::RecursionLimitExceeded => ParserErrorProto {
                inner: Some(ParserErrorInnerProto::RecursionLimitExceeded(true)),
            },
        }
    }

    pub fn to_parser_error(&self) -> ParserError {
        let Some(ref inner) = self.inner else {
            return ParserError::ParserError("Malformed protobuf message".to_string());
        };

        match inner {
            ParserErrorInnerProto::TokenizerError(msg) => {
                ParserError::TokenizerError(msg.to_string())
            }
            ParserErrorInnerProto::ParserError(msg) => ParserError::ParserError(msg.to_string()),
            ParserErrorInnerProto::RecursionLimitExceeded(_) => ParserError::RecursionLimitExceeded,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use datafusion::sql::sqlparser::parser::ParserError;
    use prost::Message;

    #[test]
    fn test_parser_error_roundtrip() {
        let test_cases = vec![
            ParserError::ParserError("syntax error".to_string()),
            ParserError::TokenizerError("tokenizer error".to_string()),
            ParserError::RecursionLimitExceeded,
        ];

        for original_error in test_cases {
            let proto = ParserErrorProto::from_parser_error(&original_error);
            let proto = ParserErrorProto::decode(proto.encode_to_vec().as_ref()).unwrap();
            let recovered_error = proto.to_parser_error();

            assert_eq!(original_error.to_string(), recovered_error.to_string());
        }
    }

    #[test]
    fn test_malformed_protobuf_message() {
        let malformed_proto = ParserErrorProto { inner: None };
        let recovered_error = malformed_proto.to_parser_error();
        assert!(matches!(recovered_error, ParserError::ParserError(_)));
    }
}