Parse WHERE predicates.
(text: &str)
| 8 | |
| 9 | /// Parse WHERE predicates. |
| 10 | pub(super) fn parse_where(text: &str) -> crate::Result<Vec<WherePredicate>> { |
| 11 | let trimmed = text.trim(); |
| 12 | if trimmed.is_empty() { |
| 13 | return Ok(Vec::new()); |
| 14 | } |
| 15 | |
| 16 | let mut predicates = Vec::new(); |
| 17 | let parts = split_by_and(trimmed); |
| 18 | |
| 19 | for part in parts { |
| 20 | let part = part.trim(); |
| 21 | if part.is_empty() { |
| 22 | continue; |
| 23 | } |
| 24 | |
| 25 | let upper_part = part.to_uppercase(); |
| 26 | |
| 27 | // NOT EXISTS { MATCH ... } |
| 28 | if upper_part.starts_with("NOT EXISTS") { |
| 29 | let brace_start = part.find('{').ok_or_else(|| crate::Error::BadRequest { |
| 30 | detail: "NOT EXISTS requires { MATCH ... }".to_string(), |
| 31 | })?; |
| 32 | let brace_end = part.rfind('}').ok_or_else(|| crate::Error::BadRequest { |
| 33 | detail: "unclosed '{' in NOT EXISTS".to_string(), |
| 34 | })?; |
| 35 | let inner = part[brace_start + 1..brace_end].trim(); |
| 36 | let inner_clauses = parse_match_clauses(inner)?; |
| 37 | if let Some(clause) = inner_clauses.into_iter().next() { |
| 38 | predicates.push(WherePredicate::NotExists { |
| 39 | sub_pattern: clause, |
| 40 | }); |
| 41 | } |
| 42 | continue; |
| 43 | } |
| 44 | |
| 45 | // Simple comparison: `a.name = 'Alice'` or `a.age > 25`. |
| 46 | if let Some(pred) = parse_comparison_predicate(part) { |
| 47 | predicates.push(pred); |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | Ok(predicates) |
| 52 | } |
| 53 | |
| 54 | /// Parse a comparison predicate: `a.name = 'Alice'`, `a.age > 25`. |
| 55 | fn parse_comparison_predicate(text: &str) -> Option<WherePredicate> { |
no test coverage detected