Implement missing errors for missing clauses on DEFINE-statements (#3356)

This commit is contained in:
Micha de Vries 2024-01-19 12:35:52 +00:00 committed by GitHub
parent 4e1b1cff21
commit 595c994062
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 86 additions and 10 deletions

View file

@ -4,7 +4,7 @@ use super::super::super::{
error::{expect_tag_no_case, expected}, error::{expect_tag_no_case, expected},
literal::{ident, strand}, literal::{ident, strand},
value::{value, values}, value::{value, values},
IResult, IResult, ParseError,
}; };
use crate::sql::{statements::DefineEventStatement, Strand, Value, Values}; use crate::sql::{statements::DefineEventStatement, Strand, Value, Values};
use nom::{ use nom::{
@ -13,6 +13,7 @@ use nom::{
combinator::{cut, opt}, combinator::{cut, opt},
multi::many0, multi::many0,
sequence::tuple, sequence::tuple,
Err,
}; };
pub fn event(i: &str) -> IResult<&str, DefineEventStatement> { pub fn event(i: &str) -> IResult<&str, DefineEventStatement> {
@ -52,7 +53,11 @@ pub fn event(i: &str) -> IResult<&str, DefineEventStatement> {
} }
// Check necessary options // Check necessary options
if res.then.is_empty() { if res.then.is_empty() {
// TODO throw error return Err(Err::Failure(ParseError::ExplainedExpected {
tried: i,
expected: "a THEN clause",
explained: "An event requires a THEN clause to be defined.",
}));
} }
// Return the statement // Return the statement
Ok((i, res)) Ok((i, res))
@ -91,3 +96,17 @@ fn event_comment(i: &str) -> IResult<&str, DefineEventOption> {
let (i, v) = cut(strand)(i)?; let (i, v) = cut(strand)(i)?;
Ok((i, DefineEventOption::Comment(v))) Ok((i, DefineEventOption::Comment(v)))
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn define_event_without_then_clause() {
let sql = "EVENT test ON test";
let res = event(sql);
assert_eq!(res.is_err(), true)
}
}

View file

@ -7,13 +7,17 @@ use super::super::super::{
part::index, part::index,
IResult, IResult,
}; };
use crate::sql::{statements::DefineIndexStatement, Idioms, Index, Strand}; use crate::{
sql::{statements::DefineIndexStatement, Idioms, Index, Strand},
syn::v1::ParseError,
};
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::tag_no_case, bytes::complete::tag_no_case,
combinator::{cut, opt}, combinator::{cut, opt},
multi::many0, multi::many0,
sequence::tuple, sequence::tuple,
Err,
}; };
pub fn index(i: &str) -> IResult<&str, DefineIndexStatement> { pub fn index(i: &str) -> IResult<&str, DefineIndexStatement> {
@ -52,7 +56,11 @@ pub fn index(i: &str) -> IResult<&str, DefineIndexStatement> {
} }
// Check necessary options // Check necessary options
if res.cols.is_empty() { if res.cols.is_empty() {
// TODO throw error return Err(Err::Failure(ParseError::ExplainedExpected {
tried: i,
expected: "a COLUMNS or FIELDS clause",
explained: "An index requires a COLUMNS or FIELDS clause to be defined.",
}));
} }
// Return the statement // Return the statement
Ok((i, res)) Ok((i, res))
@ -231,4 +239,12 @@ mod tests {
"DEFINE INDEX my_index ON my_table FIELDS my_col MTREE DIMENSION 4 DIST EUCLIDEAN TYPE F64 CAPACITY 40 DOC_IDS_ORDER 100 DOC_IDS_CACHE 100 MTREE_CACHE 100" "DEFINE INDEX my_index ON my_table FIELDS my_col MTREE DIMENSION 4 DIST EUCLIDEAN TYPE F64 CAPACITY 40 DOC_IDS_ORDER 100 DOC_IDS_CACHE 100 MTREE_CACHE 100"
); );
} }
#[test]
fn define_index_without_columns_clause() {
let sql = "INDEX test ON test";
let res = index(sql);
assert_eq!(res.is_err(), true)
}
} }

View file

@ -7,10 +7,13 @@ use super::super::super::{
value::value, value::value,
IResult, IResult,
}; };
use crate::sql::{statements::DefineParamStatement, Permission, Strand, Value}; use crate::{
sql::{statements::DefineParamStatement, Permission, Strand, Value},
syn::v1::ParseError,
};
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,
multi::many0, multi::many0, Err,
}; };
pub fn param(i: &str) -> IResult<&str, DefineParamStatement> { pub fn param(i: &str) -> IResult<&str, DefineParamStatement> {
@ -41,7 +44,11 @@ pub fn param(i: &str) -> IResult<&str, DefineParamStatement> {
} }
// Check necessary options // Check necessary options
if res.value.is_none() { if res.value.is_none() {
// TODO throw error return Err(Err::Failure(ParseError::ExplainedExpected {
tried: i,
expected: "a VALUE clause",
explained: "A param requires a VALUE clause to be defined.",
}));
} }
// Return the statement // Return the statement
Ok((i, res)) Ok((i, res))
@ -80,3 +87,17 @@ fn param_permissions(i: &str) -> IResult<&str, DefineParamOption> {
let (i, v) = cut(permission)(i)?; let (i, v) = cut(permission)(i)?;
Ok((i, DefineParamOption::Permissions(v))) Ok((i, DefineParamOption::Permissions(v)))
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn define_param_without_value_clause() {
let sql = "PARAM test";
let res = param(sql);
assert_eq!(res.is_err(), true)
}
}

View file

@ -8,8 +8,10 @@ use super::super::super::{
part::base_or_scope, part::base_or_scope,
IResult, IResult,
}; };
use crate::sql::{statements::DefineTokenStatement, Algorithm, Strand}; use crate::{
#[cfg(not(feature = "jwks"))] sql::{statements::DefineTokenStatement, Algorithm, Strand},
syn::v1::ParseError,
};
use nom::Err; use nom::Err;
use nom::{branch::alt, bytes::complete::tag_no_case, combinator::cut, multi::many0}; use nom::{branch::alt, bytes::complete::tag_no_case, combinator::cut, multi::many0};
@ -55,7 +57,11 @@ pub fn token(i: &str) -> IResult<&str, DefineTokenStatement> {
} }
// Check necessary options // Check necessary options
if res.code.is_empty() { if res.code.is_empty() {
// TODO throw error return Err(Err::Failure(ParseError::ExplainedExpected {
tried: i,
expected: "a VALUE clause",
explained: "A token requires a VALUE clause to be defined.",
}));
} }
// Return the statement // Return the statement
Ok((i, res)) Ok((i, res))
@ -94,3 +100,17 @@ fn token_comment(i: &str) -> IResult<&str, DefineTokenOption> {
let (i, v) = cut(strand)(i)?; let (i, v) = cut(strand)(i)?;
Ok((i, DefineTokenOption::Comment(v))) Ok((i, DefineTokenOption::Comment(v)))
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn define_token_without_value_clause() {
let sql = "TOKEN test ON test";
let res = token(sql);
assert_eq!(res.is_err(), true)
}
}