Skip to content

Commit

Permalink
NONLINEARALGORITHMINDEX command inclusions
Browse files Browse the repository at this point in the history
  • Loading branch information
deven96 committed Sep 25, 2024
1 parent 1251424 commit 2bd59cd
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 2 deletions.
110 changes: 109 additions & 1 deletion ahnlich/dsl/src/db.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use ahnlich_types::{db::DBQuery, keyval::StoreName, metadata::MetadataKey};
use ahnlich_types::{
db::DBQuery, keyval::StoreName, metadata::MetadataKey, similarity::NonLinearAlgorithm,
};
use pest::Parser;
use pest_derive::Parser;

Expand All @@ -8,6 +10,13 @@ use crate::error::DslError;
#[grammar = "syntax/db.pest"]
struct DBQueryParser;

fn to_non_linear(input: &str) -> Option<NonLinearAlgorithm> {
match input.to_lowercase().trim() {
"kdtree" => Some(NonLinearAlgorithm::KDTree),
_ => None,
}
}

// Parse raw strings separated by ; into a Vec<DBQuery>. Examples include but are not restricted
// to
//
Expand All @@ -17,6 +26,17 @@ struct DBQueryParser;
// INFOSERVER
// DROPSTORE store_name IF EXISTS
// CREATEPREDINDEX (key_1, key_2) in store_name
// DROPPREDINDEX IF EXISTS (key1, key2) in store_name
// CREATENONLINEARALGORITHMINDEX (kdtree) in store_name
// DROPNONLINEARALGORITHMINDEX IF EXISTS (kdtree) in store_name
//
// #TODO
// SET
// DELKEY
// CREATESTORE
// GETKEY
// GETPRED
// GETSIMN
pub fn parse_db_query(input: &str) -> Result<Vec<DBQuery>, DslError> {
let pairs = DBQueryParser::parse(Rule::query, input).map_err(Box::new)?;
let statements = pairs.into_iter().collect::<Vec<_>>();
Expand All @@ -29,6 +49,24 @@ pub fn parse_db_query(input: &str) -> Result<Vec<DBQuery>, DslError> {
Rule::list_clients => DBQuery::ListClients,
Rule::list_stores => DBQuery::ListStores,
Rule::info_server => DBQuery::InfoServer,
Rule::create_non_linear_algorithm_index => {
let mut inner_pairs = statement.into_inner();
let index_name_pairs = inner_pairs
.next()
.ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))?;
let non_linear_indices = index_name_pairs
.into_inner()
.flat_map(|index_pair| to_non_linear(index_pair.as_str()))
.collect();
let store = inner_pairs
.next()
.ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))?
.as_str();
DBQuery::CreateNonLinearAlgorithmIndex {
store: StoreName(store.to_string()),
non_linear_indices,
}
}
Rule::create_pred_index => {
let mut inner_pairs = statement.into_inner();
let index_name_pairs = inner_pairs
Expand All @@ -47,6 +85,32 @@ pub fn parse_db_query(input: &str) -> Result<Vec<DBQuery>, DslError> {
predicates,
}
}
Rule::drop_non_linear_algorithm_index => {
let mut inner_pairs = statement.into_inner().peekable();
let mut if_exists = false;
if let Some(next_pair) = inner_pairs.peek() {
if next_pair.as_rule() == Rule::if_exists {
inner_pairs.next(); // Consume it if needed
if_exists = true;
}
};
let index_names_pair = inner_pairs
.next()
.ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))?;
let store = inner_pairs
.next()
.ok_or(DslError::UnexpectedSpan((start_pos, end_pos)))?
.as_str();
let non_linear_indices = index_names_pair
.into_inner()
.flat_map(|index_pair| to_non_linear(index_pair.as_str()))
.collect();
DBQuery::DropNonLinearAlgorithmIndex {
store: StoreName(store.to_string()),
non_linear_indices,
error_if_not_exists: !if_exists,
}
}
Rule::drop_pred_index => {
let mut inner_pairs = statement.into_inner().peekable();
let mut if_exists = false;
Expand Down Expand Up @@ -216,4 +280,48 @@ mod tests {
}]
);
}

#[test]
fn test_create_non_linear_algorithm_parse() {
let input = r#"createnonlinearalgorithmindex (fake) in store2"#;
let DslError::UnexpectedSpan((start, end)) = parse_db_query(input).unwrap_err() else {
panic!("Unexpected error pattern found")
};
assert_eq!((start, end), (0, 46));
let input = r#"createnonlinearalgorithmindex (kdtree) in store2"#;
assert_eq!(
parse_db_query(input).expect("Could not parse query input"),
vec![DBQuery::CreateNonLinearAlgorithmIndex {
store: StoreName("store2".to_string()),
non_linear_indices: HashSet::from_iter([NonLinearAlgorithm::KDTree]),
}]
);
}

#[test]
fn test_drop_non_linear_algorithm_parse() {
let input = r#"DROPNONLINEARALGORITHMINDEX (fake) in 1234"#;
let DslError::UnexpectedSpan((start, end)) = parse_db_query(input).unwrap_err() else {
panic!("Unexpected error pattern found")
};
assert_eq!((start, end), (0, 42));
let input = r#"DROPNONLINEARALGORITHMINDEX (kdtree) in 1234"#;
assert_eq!(
parse_db_query(input).expect("Could not parse query input"),
vec![DBQuery::DropNonLinearAlgorithmIndex {
store: StoreName("1234".to_string()),
non_linear_indices: HashSet::from_iter([NonLinearAlgorithm::KDTree]),
error_if_not_exists: true,
}]
);
let input = r#"DROPNONLINEARALGORITHMINDEX IF EXISTS (kdtree) in 1234"#;
assert_eq!(
parse_db_query(input).expect("Could not parse query input"),
vec![DBQuery::DropNonLinearAlgorithmIndex {
store: StoreName("1234".to_string()),
non_linear_indices: HashSet::from_iter([NonLinearAlgorithm::KDTree]),
error_if_not_exists: false,
}]
);
}
}
17 changes: 16 additions & 1 deletion ahnlich/dsl/src/syntax/db.pest
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,36 @@ whitespace = _{ " " | "\t" }

query = _{ statement ~ (";" ~ statement) * } // Matches multiple statements separated by ;

statement = _{ ping | info_server | list_stores | list_clients | drop_store | create_pred_index | drop_pred_index | invalid_statement }
statement = _{
ping |
info_server |
list_stores |
list_clients |
drop_store |
create_pred_index |
drop_pred_index |
create_non_linear_algorithm_index |
drop_non_linear_algorithm_index |
invalid_statement
}

ping = { whitespace* ~ ^"ping" ~ whitespace* }
info_server = { whitespace* ~ ^"infoserver" ~ whitespace* }
list_stores = { whitespace* ~ ^"liststores" ~ whitespace* }
list_clients = { whitespace* ~ ^"listclients" ~ whitespace* }
drop_store = { whitespace* ~ ^"dropstore" ~ whitespace* ~ store_name ~ (if_exists | invalid_statement)? }
create_pred_index = { whitespace* ~ ^"createpredindex" ~ whitespace* ~ "(" ~ index_names ~ ")" ~ whitespace* ~ ^"in" ~ whitespace* ~ store_name }
create_non_linear_algorithm_index = { whitespace* ~ ^"createnonlinearalgorithmindex" ~ whitespace* ~ "(" ~ non_linear_algorithms ~ ")" ~ whitespace* ~ ^"in" ~ whitespace* ~ store_name}
drop_pred_index = { whitespace* ~ ^"droppredindex" ~ whitespace* ~ (if_exists)? ~ "(" ~ index_names ~ ")" ~ whitespace* ~ ^"in" ~whitespace* ~ store_name }
drop_non_linear_algorithm_index = { whitespace* ~ ^"dropnonlinearalgorithmindex" ~ whitespace* ~ (if_exists)? ~ "(" ~ non_linear_algorithms ~ ")" ~ whitespace* ~ ^"in" ~whitespace* ~ store_name }

if_exists = { whitespace* ~ ^"if" ~ whitespace* ~ ^"exists" ~ whitespace* }

// stores and predicates can be alphanumeric
store_name = { (ASCII_ALPHANUMERIC | "_" | "-")+ }
index_name = { (ASCII_ALPHANUMERIC | "_" | "-")+ }
non_linear_algorithm = { ^"kdtree" }
non_linear_algorithms = { non_linear_algorithm ~ (whitespace* ~ "," ~ whitespace* ~ non_linear_algorithm)* }
index_names = { index_name ~ (whitespace* ~ "," ~ whitespace* ~ index_name)* }

// Catch-all rule for invalid statements
Expand Down

0 comments on commit 2bd59cd

Please sign in to comment.