Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

start of work to match cql2 against json #55

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft

start of work to match cql2 against json #55

wants to merge 8 commits into from

Conversation

bitner
Copy link
Contributor

@bitner bitner commented Dec 12, 2024

WORK IN PROGRESS
TODO:

  • Arithmetic Operators
  • Comparison Operators for Number
  • Comparison Operators for Boolean
  • Comparison Operators for Text
  • Spatial Operators
  • Temporal Operators
  • Testing Framework for Reduce
  • Implement Array Operators
  • Implement Like
  • Implement In
  • Implement Is Null
  • Implement Not
  • Implement Between
  • Implement Cast from BBox to geos geometry
  • Implement basic comparison ops for singular timestamps / dates
  • More tests!

@bitner
Copy link
Contributor Author

bitner commented Dec 12, 2024

So, trying to set this up so that the reduce function can actually be used for any CQL2 expression to collapse things that don't need to go through to the base data. So say you had a CQL2 query like foo = 2 +7, you could use reduce to convert that to foo = 9 . To do that, I'll need to make the json input an option, if it can look up a property in the json, it will replace it with the value in that json. The matches function just looks to see if running reduce has boiled the entire expression down into an Expr::Bool and if so returns that value, if it couldn't reduce it all the way it returns an error.

Cargo.toml Outdated
@@ -24,9 +24,11 @@ keywords = ["cql2"]

[dependencies]
boon = "0.6.0"
derive_is_enum_variant = "0.1.1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I use https://crates.io/crates/enum-as-inner for this functionality. It looks to be much more popular and more recently maintained.

Copy link
Member

@kylebarron kylebarron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really know CQL so I didn't look too closely at the body of reduce (yet)

src/expr.rs Outdated
@@ -35,7 +37,222 @@ pub enum Expr {
Geometry(Geometry),
}

impl From<Value> for Expr {
fn from(v: Value) -> Expr {
let e: Expr = serde_json::from_value(v).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: If there's an unwrap in there, you usually should be implementing TryFrom instead of From.

src/expr.rs Outdated
}


impl TryInto<f64> for Expr {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should implement TryFrom instead of TryInto: https://doc.rust-lang.org/std/convert/trait.TryInto.html

cli/src/lib.rs Outdated Show resolved Hide resolved
src/expr.rs Outdated Show resolved Hide resolved
src/expr.rs Outdated
/// );
///
/// let mut expr: Expr = serde_json::from_value(expr_json).unwrap();
/// println!("Initial {:?}", expr);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we're WIP testing, but I find that println debugging is quicker+better when it's in library tests, not in doctests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also when it's a library test and not a doctest you can just use dbg!() instead of having to use string formatting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh. I am well known for copious use of print statements when in WIP mode. Will definitely clear when marking for merge.

src/expr.rs Outdated Show resolved Hide resolved
src/expr.rs Outdated Show resolved Hide resolved
src/expr.rs Outdated
///
///
/// ```
pub fn reduce(&mut self, j: &Value) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be more ergonomic as a consume-then-return:

Suggested change
pub fn reduce(&mut self, j: &Value) {
pub fn reduce(self, j: &Value) -> Expr {

That way you can just return directly from those match branches below rather than assigning to *self.

src/expr.rs Outdated
Comment on lines 136 to 146
let b: Result<bool, _> = arg.as_ref().clone().try_into();
match b {
Ok(true) => anytrue = true,
Ok(false) => {
alltrue = false;
}
_ => {
alltrue = false;
allbool = false;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the .as_ref().clone() removal, but I'd guess there'd be a way to avoid that? I'm working in the browser right now so don't have IDE powers to make me less dumb 😄:

Suggested change
let b: Result<bool, _> = arg.as_ref().clone().try_into();
match b {
Ok(true) => anytrue = true,
Ok(false) => {
alltrue = false;
}
_ => {
alltrue = false;
allbool = false;
}
}
if let Ok(bool) = arg.try_into() {
if bool {
anytrue = true;
} else {
alltrue = false;
}
} else {
alltrue = false;
allbool = false;
// Can you break here?
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't break there as the main thing that loop is doing is to run reduce against each arg. We are just doing the bool check as an addition so we only have to loop through the args once.

src/expr.rs Outdated
Comment on lines 249 to 254
let mut e = self.clone();
e.reduce(j);
match e {
Expr::Bool(v) => Ok(v),
_ => Err(()),
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How often will we re-use matches? Can we make this consuming (taking self) and let the caller do a clone themselves? Cloning inside a simple method like this feels a bit off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants