Check that objects properties are recognized by the query planner (#3643)
This commit is contained in:
parent
03e9998ff1
commit
1784a1202e
10 changed files with 52 additions and 42 deletions
|
@ -10,10 +10,9 @@ use crate::sql::Ident;
|
||||||
use crate::sql::{filter::Filter, statements::DefineAnalyzerStatement, Strand, Tokenizer};
|
use crate::sql::{filter::Filter, statements::DefineAnalyzerStatement, Strand, Tokenizer};
|
||||||
#[cfg(feature = "sql2")]
|
#[cfg(feature = "sql2")]
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
use nom::{
|
use nom::{branch::alt, bytes::complete::tag_no_case, combinator::cut, multi::many0};
|
||||||
branch::alt, bytes::complete::tag_no_case, combinator::cut, combinator::opt, multi::many0,
|
#[cfg(feature = "sql2")]
|
||||||
sequence::tuple,
|
use nom::{combinator::opt, sequence::tuple};
|
||||||
};
|
|
||||||
|
|
||||||
pub fn analyzer(i: &str) -> IResult<&str, DefineAnalyzerStatement> {
|
pub fn analyzer(i: &str) -> IResult<&str, DefineAnalyzerStatement> {
|
||||||
let (i, _) = tag_no_case("ANALYZER")(i)?;
|
let (i, _) = tag_no_case("ANALYZER")(i)?;
|
||||||
|
|
|
@ -7,10 +7,9 @@ use super::super::super::{
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
use crate::sql::{statements::DefineDatabaseStatement, ChangeFeed, Strand};
|
use crate::sql::{statements::DefineDatabaseStatement, ChangeFeed, Strand};
|
||||||
use nom::{
|
use nom::{branch::alt, bytes::complete::tag_no_case, combinator::cut, multi::many0};
|
||||||
branch::alt, bytes::complete::tag_no_case, combinator::cut, combinator::opt, multi::many0,
|
#[cfg(feature = "sql2")]
|
||||||
sequence::tuple,
|
use nom::{combinator::opt, sequence::tuple};
|
||||||
};
|
|
||||||
|
|
||||||
pub fn database(i: &str) -> IResult<&str, DefineDatabaseStatement> {
|
pub fn database(i: &str) -> IResult<&str, DefineDatabaseStatement> {
|
||||||
let (i, _) = alt((tag_no_case("DB"), tag_no_case("DATABASE")))(i)?;
|
let (i, _) = alt((tag_no_case("DB"), tag_no_case("DATABASE")))(i)?;
|
||||||
|
|
|
@ -15,10 +15,10 @@ use nom::{
|
||||||
bytes::complete::{tag, tag_no_case},
|
bytes::complete::{tag, tag_no_case},
|
||||||
character::complete::char,
|
character::complete::char,
|
||||||
combinator::cut,
|
combinator::cut,
|
||||||
combinator::opt,
|
|
||||||
multi::many0,
|
multi::many0,
|
||||||
sequence::tuple,
|
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "sql2")]
|
||||||
|
use nom::{combinator::opt, sequence::tuple};
|
||||||
|
|
||||||
pub fn function(i: &str) -> IResult<&str, DefineFunctionStatement> {
|
pub fn function(i: &str) -> IResult<&str, DefineFunctionStatement> {
|
||||||
let (i, _) = tag_no_case("FUNCTION")(i)?;
|
let (i, _) = tag_no_case("FUNCTION")(i)?;
|
||||||
|
|
|
@ -6,10 +6,9 @@ use super::super::super::{
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
use crate::sql::{statements::DefineNamespaceStatement, Strand};
|
use crate::sql::{statements::DefineNamespaceStatement, Strand};
|
||||||
use nom::{
|
use nom::{branch::alt, bytes::complete::tag_no_case, combinator::cut, multi::many0};
|
||||||
branch::alt, bytes::complete::tag_no_case, combinator::cut, combinator::opt, multi::many0,
|
#[cfg(feature = "sql2")]
|
||||||
sequence::tuple,
|
use nom::{combinator::opt, sequence::tuple};
|
||||||
};
|
|
||||||
|
|
||||||
pub fn namespace(i: &str) -> IResult<&str, DefineNamespaceStatement> {
|
pub fn namespace(i: &str) -> IResult<&str, DefineNamespaceStatement> {
|
||||||
let (i, _) = alt((tag_no_case("NS"), tag_no_case("NAMESPACE")))(i)?;
|
let (i, _) = alt((tag_no_case("NS"), tag_no_case("NAMESPACE")))(i)?;
|
||||||
|
|
|
@ -13,8 +13,10 @@ use crate::{
|
||||||
};
|
};
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt, bytes::complete::tag_no_case, character::complete::char, combinator::cut,
|
branch::alt, bytes::complete::tag_no_case, character::complete::char, combinator::cut,
|
||||||
combinator::opt, multi::many0, sequence::tuple, Err,
|
multi::many0, Err,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "sql2")]
|
||||||
|
use nom::{combinator::opt, sequence::tuple};
|
||||||
|
|
||||||
pub fn param(i: &str) -> IResult<&str, DefineParamStatement> {
|
pub fn param(i: &str) -> IResult<&str, DefineParamStatement> {
|
||||||
let (i, _) = tag_no_case("PARAM")(i)?;
|
let (i, _) = tag_no_case("PARAM")(i)?;
|
||||||
|
|
|
@ -7,10 +7,9 @@ use super::super::super::{
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
use crate::sql::{statements::DefineScopeStatement, Duration, Strand, Value};
|
use crate::sql::{statements::DefineScopeStatement, Duration, Strand, Value};
|
||||||
use nom::{
|
use nom::{branch::alt, bytes::complete::tag_no_case, combinator::cut, multi::many0};
|
||||||
branch::alt, bytes::complete::tag_no_case, combinator::cut, combinator::opt, multi::many0,
|
#[cfg(feature = "sql2")]
|
||||||
sequence::tuple,
|
use nom::{combinator::opt, sequence::tuple};
|
||||||
};
|
|
||||||
|
|
||||||
pub fn scope(i: &str) -> IResult<&str, DefineScopeStatement> {
|
pub fn scope(i: &str) -> IResult<&str, DefineScopeStatement> {
|
||||||
let (i, _) = tag_no_case("SCOPE")(i)?;
|
let (i, _) = tag_no_case("SCOPE")(i)?;
|
||||||
|
|
|
@ -9,10 +9,9 @@ use super::super::super::{
|
||||||
use crate::sql::{
|
use crate::sql::{
|
||||||
statements::DefineTableStatement, ChangeFeed, Permission, Permissions, Strand, View,
|
statements::DefineTableStatement, ChangeFeed, Permission, Permissions, Strand, View,
|
||||||
};
|
};
|
||||||
use nom::{
|
use nom::{branch::alt, bytes::complete::tag_no_case, combinator::cut, multi::many0};
|
||||||
branch::alt, bytes::complete::tag_no_case, combinator::cut, combinator::opt, multi::many0,
|
#[cfg(feature = "sql2")]
|
||||||
sequence::tuple,
|
use nom::{combinator::opt, sequence::tuple};
|
||||||
};
|
|
||||||
|
|
||||||
pub fn table(i: &str) -> IResult<&str, DefineTableStatement> {
|
pub fn table(i: &str) -> IResult<&str, DefineTableStatement> {
|
||||||
let (i, _) = tag_no_case("TABLE")(i)?;
|
let (i, _) = tag_no_case("TABLE")(i)?;
|
||||||
|
|
|
@ -13,10 +13,9 @@ use crate::{
|
||||||
syn::v1::ParseError,
|
syn::v1::ParseError,
|
||||||
};
|
};
|
||||||
use nom::Err;
|
use nom::Err;
|
||||||
use nom::{
|
use nom::{branch::alt, bytes::complete::tag_no_case, combinator::cut, multi::many0};
|
||||||
branch::alt, bytes::complete::tag_no_case, combinator::cut, combinator::opt, multi::many0,
|
#[cfg(feature = "sql2")]
|
||||||
sequence::tuple,
|
use nom::{combinator::opt, sequence::tuple};
|
||||||
};
|
|
||||||
|
|
||||||
pub fn token(i: &str) -> IResult<&str, DefineTokenStatement> {
|
pub fn token(i: &str) -> IResult<&str, DefineTokenStatement> {
|
||||||
let (i, _) = tag_no_case("TOKEN")(i)?;
|
let (i, _) = tag_no_case("TOKEN")(i)?;
|
||||||
|
|
|
@ -15,11 +15,11 @@ use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::tag_no_case,
|
bytes::complete::tag_no_case,
|
||||||
combinator::cut,
|
combinator::cut,
|
||||||
combinator::opt,
|
|
||||||
multi::{many0, separated_list1},
|
multi::{many0, separated_list1},
|
||||||
sequence::tuple,
|
|
||||||
Err,
|
Err,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature = "sql2")]
|
||||||
|
use nom::{combinator::opt, sequence::tuple};
|
||||||
|
|
||||||
pub fn user(i: &str) -> IResult<&str, DefineUserStatement> {
|
pub fn user(i: &str) -> IResult<&str, DefineUserStatement> {
|
||||||
let (i, _) = tag_no_case("USER")(i)?;
|
let (i, _) = tag_no_case("USER")(i)?;
|
||||||
|
|
|
@ -1147,6 +1147,9 @@ async fn select_unique_contains() -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
// This test checks that:
|
||||||
|
// 1. Datetime are recognized by the query planner
|
||||||
|
// 2. we can take the value store in a variable
|
||||||
async fn select_with_datetime_value() -> Result<(), Error> {
|
async fn select_with_datetime_value() -> Result<(), Error> {
|
||||||
let dbs = new_ds().await?;
|
let dbs = new_ds().await?;
|
||||||
let ses = Session::owner().with_ns("test").with_db("test");
|
let ses = Session::owner().with_ns("test").with_db("test");
|
||||||
|
@ -1201,6 +1204,9 @@ async fn select_with_datetime_value() -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
// This test checks that:
|
||||||
|
// 1. UUID are recognized by the query planner
|
||||||
|
// 2. we can take the value from a object stored as a variable
|
||||||
async fn select_with_uuid_value() -> Result<(), Error> {
|
async fn select_with_uuid_value() -> Result<(), Error> {
|
||||||
let dbs = new_ds().await?;
|
let dbs = new_ds().await?;
|
||||||
let ses = Session::owner().with_ns("test").with_db("test");
|
let ses = Session::owner().with_ns("test").with_db("test");
|
||||||
|
@ -1208,16 +1214,21 @@ async fn select_with_uuid_value() -> Result<(), Error> {
|
||||||
let sql = "
|
let sql = "
|
||||||
DEFINE INDEX sessionUid ON sessions FIELDS sessionUid;
|
DEFINE INDEX sessionUid ON sessions FIELDS sessionUid;
|
||||||
CREATE sessions:1 CONTENT { sessionUid: u'00ad70db-f435-442e-9012-1cd853102084' };
|
CREATE sessions:1 CONTENT { sessionUid: u'00ad70db-f435-442e-9012-1cd853102084' };
|
||||||
|
LET $sess = { uuid: u'00ad70db-f435-442e-9012-1cd853102084' };
|
||||||
SELECT * FROM sessions WHERE sessionUid = u'00ad70db-f435-442e-9012-1cd853102084' EXPLAIN;
|
SELECT * FROM sessions WHERE sessionUid = u'00ad70db-f435-442e-9012-1cd853102084' EXPLAIN;
|
||||||
SELECT * FROM sessions WHERE sessionUid = u'00ad70db-f435-442e-9012-1cd853102084';";
|
SELECT * FROM sessions WHERE sessionUid = $sess.uuid EXPLAIN;
|
||||||
|
SELECT * FROM sessions WHERE sessionUid = u'00ad70db-f435-442e-9012-1cd853102084';
|
||||||
|
SELECT * FROM sessions WHERE sessionUid = $sess.uuid;
|
||||||
|
";
|
||||||
let mut res = dbs.execute(&sql, &ses, None).await?;
|
let mut res = dbs.execute(&sql, &ses, None).await?;
|
||||||
|
|
||||||
assert_eq!(res.len(), 4);
|
assert_eq!(res.len(), 7);
|
||||||
skip_ok(&mut res, 2)?;
|
skip_ok(&mut res, 3)?;
|
||||||
|
|
||||||
let tmp = res.remove(0).result?;
|
for _ in 0..2 {
|
||||||
let val = Value::parse(
|
let tmp = res.remove(0).result?;
|
||||||
r#"[
|
let val = Value::parse(
|
||||||
|
r#"[
|
||||||
{
|
{
|
||||||
detail: {
|
detail: {
|
||||||
plan: {
|
plan: {
|
||||||
|
@ -1230,19 +1241,22 @@ async fn select_with_uuid_value() -> Result<(), Error> {
|
||||||
operation: 'Iterate Index'
|
operation: 'Iterate Index'
|
||||||
}
|
}
|
||||||
]"#,
|
]"#,
|
||||||
);
|
);
|
||||||
assert_eq!(format!("{:#}", tmp), format!("{:#}", val));
|
assert_eq!(format!("{:#}", tmp), format!("{:#}", val));
|
||||||
|
}
|
||||||
|
|
||||||
let tmp = res.remove(0).result?;
|
for _ in 0..2 {
|
||||||
let val = Value::parse(
|
let tmp = res.remove(0).result?;
|
||||||
r#"[
|
let val = Value::parse(
|
||||||
|
r#"[
|
||||||
{
|
{
|
||||||
"id": sessions:1,
|
"id": sessions:1,
|
||||||
"sessionUid": "00ad70db-f435-442e-9012-1cd853102084"
|
"sessionUid": "00ad70db-f435-442e-9012-1cd853102084"
|
||||||
}
|
}
|
||||||
]"#,
|
]"#,
|
||||||
);
|
);
|
||||||
assert_eq!(format!("{:#}", tmp), format!("{:#}", val));
|
assert_eq!(format!("{:#}", tmp), format!("{:#}", val));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue