Bugfix: Fix inconsistant record parsing (#3076)
This commit is contained in:
parent
aac8ec8a36
commit
42f506a916
4 changed files with 89 additions and 23 deletions
|
@ -46,3 +46,23 @@ impl fmt::Display for SleepStatement {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@ use super::{
|
|||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::{tag, tag_no_case},
|
||||
character::complete::{char, multispace1},
|
||||
character::complete::{char, multispace1, satisfy},
|
||||
combinator::{eof, peek, value},
|
||||
sequence::preceded,
|
||||
sequence::{preceded, tuple},
|
||||
};
|
||||
|
||||
pub fn number(i: &str) -> IResult<&str, ()> {
|
||||
|
@ -20,12 +20,21 @@ pub fn number(i: &str) -> IResult<&str, ()> {
|
|||
value((), char(')')), // (1)
|
||||
value((), char(']')), // a[1]
|
||||
value((), char('}')), // {k: 1}
|
||||
value((), char('"')),
|
||||
value((), char('\'')),
|
||||
value((), char(';')), // SET a = 1;
|
||||
value((), char(',')), // [1, 2]
|
||||
value((), tag("..")), // thing:1..2
|
||||
value((), eof), // SET a = 1
|
||||
value((), char('"')), // r"foo:1"
|
||||
value((), char('\'')), // r'foo:1'
|
||||
value((), char(';')), // SET a = 1;
|
||||
value((), char(',')), // [1, 2]
|
||||
value((), char('[')), // thing:1[foo]
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ pub fn bracketed_value(i: &str) -> IResult<&str, Part> {
|
|||
#[cfg(test)]
|
||||
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 super::*;
|
||||
|
@ -581,4 +581,55 @@ mod tests {
|
|||
assert_eq!("[WHERE test = true]", format!("{}", out));
|
||||
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
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,6 @@ pub fn sleep(i: &str) -> IResult<&str, SleepStatement> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::dbs::test::mock;
|
||||
use crate::sql::Value;
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[test]
|
||||
fn test_sleep_statement_sec() {
|
||||
|
@ -36,15 +33,4 @@ mod tests {
|
|||
let out = res.unwrap().1;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue