diff --git a/query-algebrizer/src/clauses/predicate.rs b/query-algebrizer/src/clauses/predicate.rs index a4dc601c..986c78e4 100644 --- a/query-algebrizer/src/clauses/predicate.rs +++ b/query-algebrizer/src/clauses/predicate.rs @@ -33,6 +33,7 @@ use types::{ ColumnConstraint, EmptyBecause, Inequality, + QueryValue, }; use Known; @@ -150,16 +151,34 @@ impl ConjoiningClauses { // These arguments must be variables or instant/numeric constants. // TODO: static evaluation. #383. - let constraint = ColumnConstraint::Inequality { - operator: comparison, - left: left_v, - right: right_v, - }; + let constraint = comparison.to_constraint(left_v, right_v); self.wheres.add_intersection(constraint); Ok(()) } } +impl Inequality { + fn to_constraint(&self, left: QueryValue, right: QueryValue) -> ColumnConstraint { + match *self { + Inequality::TxAfter | + Inequality::TxBefore => { + // TODO: both ends of the range must be inside the tx partition! + // If we know the partition map -- and at this point we do, it's just + // not passed to this function -- then we can generate two constraints, + // or clamp a fixed value. + }, + _ => { + }, + } + + ColumnConstraint::Inequality { + operator: *self, + left: left, + right: right, + } + } +} + #[cfg(test)] mod testing { use super::*; diff --git a/query-algebrizer/src/types.rs b/query-algebrizer/src/types.rs index 881a95e8..be3b253a 100644 --- a/query-algebrizer/src/types.rs +++ b/query-algebrizer/src/types.rs @@ -287,6 +287,10 @@ pub enum Inequality { // Ref operators. Unpermute, Differ, + + // Tx operators. + TxAfter, + TxBefore, } impl Inequality { @@ -301,6 +305,9 @@ impl Inequality { Unpermute => "<", Differ => "<>", + + TxAfter => ">", + TxBefore => "<", } } @@ -314,6 +321,9 @@ impl Inequality { "unpermute" => Some(Inequality::Unpermute), "differ" => Some(Inequality::Differ), + + "tx-after" => Some(Inequality::TxAfter), + "tx-before" => Some(Inequality::TxBefore), _ => None, } } @@ -332,7 +342,9 @@ impl Inequality { ts }, &Unpermute | - &Differ => { + &Differ | + &TxAfter | + &TxBefore => { ValueTypeSet::of_one(ValueType::Ref) }, } @@ -351,6 +363,9 @@ impl Debug for Inequality { &Unpermute => "<", &Differ => "<>", + + &TxAfter => ">", + &TxBefore => "<", }) } } diff --git a/query-translator/tests/translate.rs b/query-translator/tests/translate.rs index bdcd91aa..7179b379 100644 --- a/query-translator/tests/translate.rs +++ b/query-translator/tests/translate.rs @@ -1115,3 +1115,22 @@ fn test_project_aggregates() { WHERE `datoms00`.a = 99)"); assert_eq!(args, vec![]); } + +#[test] +fn test_tx_before_and_after() { + let schema = prepopulated_typed_schema(ValueType::Long); + let query = r#"[:find ?x :where [?x _ _ ?tx] [(tx-after ?tx 12345)]]"#; + let SQLQuery { sql, args } = translate(&schema, query); + assert_eq!(sql, "SELECT DISTINCT \ + `datoms00`.e AS `?x` \ + FROM `datoms` AS `datoms00` \ + WHERE `datoms00`.tx > 12345"); + assert_eq!(args, vec![]); + let query = r#"[:find ?x :where [?x _ _ ?tx] [(tx-before ?tx 12345)]]"#; + let SQLQuery { sql, args } = translate(&schema, query); + assert_eq!(sql, "SELECT DISTINCT \ + `datoms00`.e AS `?x` \ + FROM `datoms` AS `datoms00` \ + WHERE `datoms00`.tx < 12345"); + assert_eq!(args, vec![]); +}