Parsing and validation for Option
Add option type and option value parsers value->literal in parser, implement Option literal
This commit is contained in:
parent
de8c6164cf
commit
6245dba4f0
8 changed files with 322 additions and 109 deletions
|
|
@ -1,16 +1,10 @@
|
|||
use minisql::type_system::DbType;
|
||||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::{tag, take_while},
|
||||
character::{complete::{alphanumeric1, anychar, char, multispace0, multispace1}, is_alphanumeric},
|
||||
combinator::peek,
|
||||
error::make_error,
|
||||
sequence::{delimited, terminated},
|
||||
IResult,
|
||||
branch::alt, bytes::complete::{tag, take_while}, character::{complete::{alphanumeric1, anychar, char, multispace0, multispace1}, is_alphanumeric}, combinator::peek, error::make_error, sequence::{delimited, terminated}, IResult, Parser
|
||||
};
|
||||
|
||||
use super::literal::parse_db_value;
|
||||
use crate::syntax::Condition;
|
||||
use super::literal::parse_literal;
|
||||
|
||||
pub fn parse_table_name(input: &str) -> IResult<&str, &str> {
|
||||
alt((
|
||||
|
|
@ -38,19 +32,22 @@ pub fn parse_column_name(input: &str) -> IResult<&str, String> {
|
|||
}
|
||||
|
||||
pub fn parse_db_type(input: &str) -> IResult<&str, DbType> {
|
||||
let (input, type_name) = alt((tag("STRING"), tag("INT"), tag("NUMBER"), tag("UUID")))(input)?;
|
||||
let db_type = match type_name {
|
||||
"STRING" => DbType::String,
|
||||
"INT" => DbType::Int,
|
||||
"UUID" => DbType::Uuid,
|
||||
"NUMBER" => DbType::Number,
|
||||
_ => {
|
||||
return Err(nom::Err::Failure(make_error(
|
||||
input,
|
||||
nom::error::ErrorKind::IsNot,
|
||||
)))
|
||||
}
|
||||
};
|
||||
let (input, db_type) = alt(
|
||||
(
|
||||
tag("STRING")
|
||||
.map(|_| DbType::String),
|
||||
tag("INT")
|
||||
.map(|_| DbType::Int),
|
||||
tag("NUMBER")
|
||||
.map(|_| DbType::Number),
|
||||
tag("UUID")
|
||||
.map(|_| DbType::Uuid),
|
||||
delimited(tag("Option("), parse_db_type, tag(")"))
|
||||
.map(|ty| {
|
||||
DbType::Option(Box::new(ty))
|
||||
})
|
||||
)
|
||||
)(input)?;
|
||||
Ok((input, db_type))
|
||||
}
|
||||
|
||||
|
|
@ -70,8 +67,8 @@ fn parse_equality(input: &str) -> IResult<&str, Condition> {
|
|||
let (input, _) = multispace0(input)?;
|
||||
let (input, _) = char('=')(input)?;
|
||||
let (input, _) = multispace0(input)?;
|
||||
let (input, db_value) = parse_db_value(input)?;
|
||||
Ok((input, Condition::Eq(column_name, db_value)))
|
||||
let (input, lit) = parse_literal(input)?;
|
||||
Ok((input, Condition::Eq(column_name, lit)))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -79,15 +76,15 @@ mod tests {
|
|||
use minisql::type_system::DbType;
|
||||
|
||||
use crate::parsing::common::{parse_db_type, parse_equality, parse_identifier};
|
||||
use crate::parsing::literal::Literal;
|
||||
use crate::syntax::Condition;
|
||||
|
||||
#[test]
|
||||
fn test_parse_equality() {
|
||||
use minisql::type_system::Value;
|
||||
match parse_equality("id = 1") {
|
||||
Ok(("", Condition::Eq(column_name, value))) => {
|
||||
assert!(column_name.eq("id"));
|
||||
assert_eq!(value, Value::Int(1))
|
||||
assert_eq!(value, Literal::Int(1))
|
||||
}
|
||||
_ => {
|
||||
panic!("should parse");
|
||||
|
|
@ -127,4 +124,20 @@ mod tests {
|
|||
Err(_)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_option_string_type() {
|
||||
assert_eq!(
|
||||
parse_db_type("Option(STRING)").expect("should parse").1,
|
||||
DbType::Option(Box::new(DbType::String))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_nested_option_int_type() {
|
||||
assert_eq!(
|
||||
parse_db_type("Option(Option(Option(INT)))").expect("should parse").1,
|
||||
DbType::Option(Box::new(DbType::Option(Box::new(DbType::Option(Box::new(DbType::Int))))))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue