Skip to content

Commit

Permalink
feat(parser): allow quoted tables, where columns
Browse files Browse the repository at this point in the history
  • Loading branch information
Fyko committed Oct 12, 2023
1 parent 97da276 commit f0daac9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 17 deletions.
15 changes: 12 additions & 3 deletions scyllax-parser/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn parse_string(input: &str) -> IResult<&str, String> {
Ok((input, alpha.clone()))
}

fn parse_escaped(input: &str) -> IResult<&str, String> {
pub fn parse_escaped(input: &str) -> IResult<&str, String> {
let (input, alpha) = delimited(tag("\""), alpha1, tag("\""))(input)?;
Ok((input, alpha.to_string()))
}
Expand All @@ -97,14 +97,23 @@ fn parse_number(input: &str) -> IResult<&str, usize> {
Ok((input, number.parse().unwrap()))
}

/// Parses an identifier on.. idk tbd
pub fn parse_identifier(input: &str) -> IResult<&str, &str> {
pub fn parse_string_escaped_rust_flavored_variable(input: &str) -> IResult<&str, String> {
let (input, alpha) = delimited(tag("\""), parse_rust_flavored_variable, tag("\""))(input)?;
Ok((input, alpha.to_string()))
}

pub fn parse_rust_flavored_variable(input: &str) -> IResult<&str, &str> {
recognize(pair(
alt((alpha1, tag("_"))),
many0_count(alt((alphanumeric1, tag("_")))),
))(input)
}

/// Parses an identifier on.. idk tbd
pub fn parse_identifier(input: &str) -> IResult<&str, &str> {
parse_rust_flavored_variable(input)
}

/// Parses a [`Variable::Placeholder`]
fn parse_placeholder(input: &str) -> IResult<&str, String> {
let (input, _) = tag("?")(input)?;
Expand Down
28 changes: 17 additions & 11 deletions scyllax-parser/src/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@
use nom::{
branch::alt,
bytes::complete::{tag, tag_no_case},
character::complete::{alpha1, alphanumeric1, multispace0, multispace1},
combinator::{map, opt, recognize},
character::complete::{multispace0, multispace1},
combinator::{map, opt},
error::Error,
multi::{many0_count, separated_list0},
sequence::pair,
multi::separated_list0,
Err, IResult,
};

use crate::{
common::{parse_identifier, parse_limit_clause},
common::{
parse_identifier, parse_limit_clause, parse_rust_flavored_variable,
parse_string_escaped_rust_flavored_variable,
},
r#where::{parse_where_clause, WhereClause},
Column, Value,
};
Expand Down Expand Up @@ -79,11 +81,15 @@ fn parse_asterisk(input: &str) -> IResult<&str, Column> {
Ok((input, Column::Asterisk))
}

fn parse_table_name(input: &str) -> IResult<&str, &str> {
recognize(pair(
alt((alpha1, tag("_"))),
many0_count(alt((alphanumeric1, tag("_")))),
))(input)
fn parse_table_name(input: &str) -> IResult<&str, String> {
let (input, table) = alt((
map(parse_string_escaped_rust_flavored_variable, |x| {
format!("\"{x}\"")
}),
map(parse_rust_flavored_variable, |x: &str| x.to_string()),
))(input)?;

Ok((input, table.clone()))
}

/// Parses a select query
Expand All @@ -106,7 +112,7 @@ pub fn parse_select(input: &str) -> IResult<&str, SelectQuery> {
Ok((
input,
SelectQuery {
table: table.to_string(),
table,
columns,
condition: condition.unwrap_or_default(),
limit,
Expand Down
49 changes: 46 additions & 3 deletions scyllax-parser/src/where.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use nom::{
IResult,
};

use crate::common::{parse_identifier, parse_value, Column, Value};
use crate::common::{
parse_rust_flavored_variable, parse_string_escaped_rust_flavored_variable, parse_value, Column,
Value,
};

/// Parses a where clause with the following format:
///
Expand Down Expand Up @@ -63,9 +66,20 @@ pub enum ComparisonOperator {
ContainsKey,
}

fn parse_where_column(input: &str) -> IResult<&str, String> {
let (input, col) = alt((
map(parse_string_escaped_rust_flavored_variable, |x| {
format!("\"{x}\"")
}),
map(parse_rust_flavored_variable, |x: &str| x.to_string()),
))(input)?;

Ok((input, col.clone()))
}

/// Parses a single where condition
fn parse_where_condition(input: &str) -> IResult<&str, WhereClause> {
let (input, column) = parse_identifier(input)?;
let (input, column) = parse_where_column(input)?;
let (input, _) = multispace1(input)?;
let (input, operator) = parse_comparison_operator(input)?;
let (input, _) = multispace1(input)?;
Expand All @@ -74,7 +88,7 @@ fn parse_where_condition(input: &str) -> IResult<&str, WhereClause> {
Ok((
input,
WhereClause {
column: Column::Identifier(column.to_string()),
column: Column::Identifier(column),
operator,
value,
},
Expand Down Expand Up @@ -103,6 +117,35 @@ mod test {
use crate::*;
use pretty_assertions::assert_eq;

#[test]
fn test_funky_casing() {
assert_eq!(
parse_where_clause(
r#"where "userId" = ? and "actionOperation" = ? and "timeBucket" = ?"#
),
Ok((
"",
vec![
WhereClause {
column: Column::Identifier(r#""userId""#.to_string()),
operator: ComparisonOperator::Equal,
value: Value::Variable(Variable::Placeholder)
},
WhereClause {
column: Column::Identifier(r#""actionOperation""#.to_string()),
operator: ComparisonOperator::Equal,
value: Value::Variable(Variable::Placeholder)
},
WhereClause {
column: Column::Identifier(r#""timeBucket""#.to_string()),
operator: ComparisonOperator::Equal,
value: Value::Variable(Variable::Placeholder)
}
]
))
);
}

#[test]
fn test_parse_single_where_clause() {
assert_eq!(
Expand Down

0 comments on commit f0daac9

Please sign in to comment.