A tool to compile SQL to Elasticsearch queries
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

parser.rs 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. use std::{iter::Peekable, slice::Iter};
  2. use crate::ast::{Field, KIdentifier, KNumber, KString, KValue, Select, Where};
  3. use crate::error::KappeError;
  4. use crate::token::{Token, TokenType};
  5. pub fn parse(tokens: Vec<Token>) -> Result<Select, KappeError> {
  6. parse_select_expression(&mut tokens.iter().peekable())
  7. }
  8. fn parse_select_expression(tokens: &mut Peekable<Iter<Token>>) -> Result<Select, KappeError> {
  9. eat(tokens, TokenType::Select)?;
  10. let fields = parse_fields(tokens)?;
  11. eat(tokens, TokenType::From)?;
  12. let source = eat(tokens, TokenType::Identfiier).and_then(|t| Ok(KIdentifier::new(&t.value)))?;
  13. let where_clause = parse_where_clause(tokens)?;
  14. Ok(Select {
  15. fields,
  16. source,
  17. where_clause,
  18. })
  19. }
  20. fn parse_fields(tokens: &mut Peekable<Iter<Token>>) -> Result<Vec<Field>, KappeError> {
  21. if current_token_is(tokens, TokenType::Star) {
  22. eat(tokens, TokenType::Star).and_then(|_| Ok(vec![Field::Star]))
  23. } else {
  24. let mut fields: Vec<Field> = vec![];
  25. loop {
  26. let field = eat(tokens, TokenType::Identfiier)?;
  27. fields.push(Field::Named(field.value.clone()));
  28. if current_token_is(tokens, TokenType::Comma) {
  29. eat(tokens, TokenType::Comma)?;
  30. } else {
  31. break;
  32. }
  33. }
  34. Ok(fields)
  35. }
  36. }
  37. fn parse_where_clause(tokens: &mut Peekable<Iter<Token>>) -> Result<Option<Where>, KappeError> {
  38. let where_clause = if current_token_is(tokens, TokenType::Where) {
  39. eat(tokens, TokenType::Where)?;
  40. let predicate = parse_predicate(tokens)?;
  41. if current_token_is(tokens, TokenType::Comma) {
  42. let mut predicates: Vec<Where> = vec![];
  43. predicates.push(predicate);
  44. while current_token_is(tokens, TokenType::Comma) {
  45. eat(tokens, TokenType::Comma)?;
  46. let predicate = parse_predicate(tokens)?;
  47. predicates.push(predicate);
  48. }
  49. Some(Where::And(predicates))
  50. } else {
  51. Some(predicate)
  52. }
  53. } else {
  54. None
  55. };
  56. Ok(where_clause)
  57. }
  58. fn parse_predicate(tokens: &mut Peekable<Iter<Token>>) -> Result<Where, KappeError> {
  59. let field = eat(tokens, TokenType::Identfiier)?;
  60. let field = KValue::Identifier(KIdentifier::new(&field.value));
  61. eat(tokens, TokenType::Equals)?;
  62. let value: KValue = if current_token_is(tokens, TokenType::String) {
  63. let token = eat(tokens, TokenType::String)?;
  64. Ok(KValue::String(KString::new(&token.value)))
  65. } else if current_token_is(tokens, TokenType::Number) {
  66. let token = eat(tokens, TokenType::Number)?;
  67. match token.value.parse::<f32>() {
  68. Ok(n) => Ok(KValue::Number(KNumber::new(n))),
  69. Err(_) => Err(KappeError::new("Error converting number to f32")),
  70. }
  71. } else {
  72. Err(KappeError::new(
  73. "Invalid token on right-hand side of equals sign",
  74. ))
  75. }?;
  76. Ok(Where::Equals(field, value))
  77. }
  78. fn current_token_is(tokens: &mut Peekable<Iter<Token>>, token_type: TokenType) -> bool {
  79. match tokens.peek() {
  80. Some(t) => t.token_type == token_type,
  81. None => false,
  82. }
  83. }
  84. fn eat<'a>(
  85. tokens: &'a mut Peekable<Iter<Token>>,
  86. token_type: TokenType,
  87. ) -> Result<&'a Token, KappeError> {
  88. match tokens.next() {
  89. Some(token) => {
  90. if token.token_type == token_type {
  91. Ok(token)
  92. } else {
  93. Err(KappeError::new(&format!(
  94. "Expected {} but got {}",
  95. token_type, token.token_type
  96. )))
  97. }
  98. }
  99. None => Err(KappeError::new("Unexpected end of tokens")),
  100. }
  101. }
  102. #[cfg(test)]
  103. mod tests {
  104. use super::*;
  105. use crate::lexer::scan;
  106. fn _parse(input: &str) -> Result<Select, KappeError> {
  107. let tokens = scan(input).unwrap();
  108. parse(tokens)
  109. }
  110. #[test]
  111. fn it_parses_a_simple_select() {
  112. assert_eq!(
  113. _parse("SELECT * FROM index").unwrap(),
  114. Select {
  115. fields: vec![Field::Star],
  116. source: KIdentifier::new("index"),
  117. where_clause: None
  118. },
  119. )
  120. }
  121. #[test]
  122. fn it_parses_a_select_with_field() {
  123. assert_eq!(
  124. _parse("SELECT field FROM index").unwrap(),
  125. Select {
  126. fields: vec![Field::Named("field".to_string())],
  127. source: KIdentifier::new("index"),
  128. where_clause: None
  129. },
  130. )
  131. }
  132. #[test]
  133. fn it_parses_a_select_with_multiple_fields() {
  134. assert_eq!(
  135. _parse("SELECT field_one, field_two FROM index").unwrap(),
  136. Select {
  137. fields: vec![
  138. Field::Named("field_one".to_string()),
  139. Field::Named("field_two".to_string())
  140. ],
  141. source: KIdentifier::new("index"),
  142. where_clause: None
  143. },
  144. )
  145. }
  146. #[test]
  147. fn it_parses_a_select_with_a_single_predicate_where_clause() {
  148. assert_eq!(
  149. _parse("SELECT * FROM index WHERE field = \"hello\"").unwrap(),
  150. Select {
  151. fields: vec![Field::Star],
  152. source: KIdentifier::new("index"),
  153. where_clause: Some(Where::Equals(
  154. KValue::Identifier(KIdentifier::new("field")),
  155. KValue::String(KString::new("hello")),
  156. ))
  157. },
  158. )
  159. }
  160. #[test]
  161. fn it_parses_a_select_with_a_numeric_predicate() {
  162. assert_eq!(
  163. _parse("SELECT * FROM index WHERE field = 123").unwrap(),
  164. Select {
  165. fields: vec![Field::Star],
  166. source: KIdentifier::new("index"),
  167. where_clause: Some(Where::Equals(
  168. KValue::Identifier(KIdentifier::new("field")),
  169. KValue::Number(KNumber::new(123.0)),
  170. ))
  171. },
  172. )
  173. }
  174. #[test]
  175. fn it_parses_a_select_with_a_multiple_predicate_where_clause() {
  176. assert_eq!(
  177. _parse("SELECT * FROM index WHERE field_one = \"hello\", field_two = \"world\"")
  178. .unwrap(),
  179. Select {
  180. fields: vec![Field::Star],
  181. source: KIdentifier::new("index"),
  182. where_clause: Some(Where::And(vec![
  183. Where::Equals(
  184. KValue::Identifier(KIdentifier::new("field_one")),
  185. KValue::String(KString::new("hello")),
  186. ),
  187. Where::Equals(
  188. KValue::Identifier(KIdentifier::new("field_two")),
  189. KValue::String(KString::new("world")),
  190. )
  191. ]))
  192. },
  193. )
  194. }
  195. }