A tool to compile SQL to Elasticsearch queries
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

parser.rs 6.6KB

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