Bugfix: Fix inconsistant record parsing (#3076)

This commit is contained in:
Mees Delzenne 2023-12-06 01:08:16 +01:00 committed by GitHub
parent aac8ec8a36
commit 42f506a916
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 23 deletions

View file

@ -46,3 +46,23 @@ impl fmt::Display for SleepStatement {
write!(f, "SLEEP {}", self.duration) write!(f, "SLEEP {}", self.duration)
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use crate::dbs::test::mock;
use crate::sql::{Duration, Value};
use std::time::{self, SystemTime};
#[tokio::test]
async fn test_sleep_compute() {
let time = SystemTime::now();
let (ctx, opt, txn) = mock().await;
let stm = SleepStatement {
duration: Duration(time::Duration::from_micros(500)),
};
let value = stm.compute(&ctx, &opt, &txn, None).await.unwrap();
assert!(time.elapsed().unwrap() >= time::Duration::from_micros(500));
assert_eq!(value, Value::None);
}
}

View file

@ -6,9 +6,9 @@ use super::{
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::{tag, tag_no_case}, bytes::complete::{tag, tag_no_case},
character::complete::{char, multispace1}, character::complete::{char, multispace1, satisfy},
combinator::{eof, peek, value}, combinator::{eof, peek, value},
sequence::preceded, sequence::{preceded, tuple},
}; };
pub fn number(i: &str) -> IResult<&str, ()> { pub fn number(i: &str) -> IResult<&str, ()> {
@ -20,12 +20,21 @@ pub fn number(i: &str) -> IResult<&str, ()> {
value((), char(')')), // (1) value((), char(')')), // (1)
value((), char(']')), // a[1] value((), char(']')), // a[1]
value((), char('}')), // {k: 1} value((), char('}')), // {k: 1}
value((), char('"')), value((), char('"')), // r"foo:1"
value((), char('\'')), value((), char('\'')), // r'foo:1'
value((), char(';')), // SET a = 1; value((), char(';')), // SET a = 1;
value((), char(',')), // [1, 2] value((), char(',')), // [1, 2]
value((), tag("..")), // thing:1..2 value((), char('[')), // thing:1[foo]
value((), eof), // SET a = 1 value((), tag("..")), // thing:1..2
value(
(),
tuple((
char('.'),
mightbespace,
satisfy(|x| x.is_alphanumeric() || x == '$' || x == '*'),
)),
), // thing:1.foo
value((), eof), // SET a = 1
)))(i) )))(i)
} }

View file

@ -276,7 +276,7 @@ pub fn bracketed_value(i: &str) -> IResult<&str, Part> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::sql::{Dir, Expression, Number, Param, Table, Thing}; use crate::sql::{Dir, Expression, Id, Number, Param, Strand, Table, Thing};
use crate::syn::test::Parse; use crate::syn::test::Parse;
use super::*; use super::*;
@ -581,4 +581,55 @@ mod tests {
assert_eq!("[WHERE test = true]", format!("{}", out)); assert_eq!("[WHERE test = true]", format!("{}", out));
assert_eq!(out, Part::Where(Value::from(Expression::parse("test = true")))); assert_eq!(out, Part::Where(Value::from(Expression::parse("test = true"))));
} }
#[test]
fn idiom_thing_number() {
let sql = "test:1.foo";
let res = idiom(sql);
let out = res.unwrap().1;
assert_eq!(
out,
Idiom(vec![
Part::Start(Value::Thing(Thing {
tb: "test".to_owned(),
id: Id::Number(1),
})),
Part::from("foo"),
])
);
}
#[test]
fn idiom_thing_index() {
let sql = "test:1['foo']";
let res = idiom(sql);
let out = res.unwrap().1;
assert_eq!(
out,
Idiom(vec![
Part::Start(Value::Thing(Thing {
tb: "test".to_owned(),
id: Id::Number(1),
})),
Part::Value(Value::Strand(Strand("foo".to_owned()))),
])
);
}
#[test]
fn idiom_thing_all() {
let sql = "test:1.*";
let res = idiom(sql);
let out = res.unwrap().1;
assert_eq!(
out,
Idiom(vec![
Part::Start(Value::Thing(Thing {
tb: "test".to_owned(),
id: Id::Number(1),
})),
Part::All
])
);
}
} }

View file

@ -17,9 +17,6 @@ pub fn sleep(i: &str) -> IResult<&str, SleepStatement> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::dbs::test::mock;
use crate::sql::Value;
use std::time::SystemTime;
#[test] #[test]
fn test_sleep_statement_sec() { fn test_sleep_statement_sec() {
@ -36,15 +33,4 @@ mod tests {
let out = res.unwrap().1; let out = res.unwrap().1;
assert_eq!("SLEEP 500ms", format!("{}", out)) assert_eq!("SLEEP 500ms", format!("{}", out))
} }
#[tokio::test]
async fn test_sleep_compute() {
let sql = "SLEEP 500ms";
let time = SystemTime::now();
let (ctx, opt, txn) = mock().await;
let (_, stm) = sleep(sql).unwrap();
let value = stm.compute(&ctx, &opt, &txn, None).await.unwrap();
assert!(time.elapsed().unwrap() >= time::Duration::microseconds(500));
assert_eq!(value, Value::None);
}
} }