Dynamic AND/OR query logic


I’m a bit stuck trying to figure out how to dynamically combine dynamic query fragments.

Let’s say I have four dynamic query fragments:

dynamic_1 = ...
dynamic_2 = ...
dynamic_3 = ...
dynamic_4 = ...

I now need to combine them together according to a user-supplied “and/or” custom logic. One example custom logic could look like this (users can use “and”, “or”, as well as parentheses):

user_logic = "(1 and 2) or (3 and 4)"

Out of this, I would need to dynamically build the following:

...where: (^dynamic_1 and ^dynamic_2) or (^dynamic_3 and ^dynamic_4)

Any ideas for how to go about this?

Thank you.

You’ll need a parser for user expressions.
Read more here https://stefan.lapers.be/posts/elixir-writing-an-expression-parser-with-nimble-parsec/ how to write a parser. Actually, this article contains an example in EBNF format, just adjust it to your needs. You can use https://github.com/princemaple/abnf_parsec to generate code from the notation, but keep in mind that EBNF!=ABNF. This is the first step. The second one is to compile output from parser to your dynamic queries.

Thank you @fuelen, will look at the links you sent now :slightly_smiling_face:

I think the second step is where my biggest problem is, even if I get the parsed output. How do I get something like a parsed “or” (for example) into a dynamic query?

Could you post an example of parsed output and dynamic queries?

Thank you for replying again, @fuelen :slight_smile:

I will get back to this, just need to do some more thinking around this.

I think I may have found a solution for how to do user “and/or” logic here (even allowing for parentheses in the user logic): https://medium.com/@fmcgeough_49791/elixir-and-dynamic-ecto-queries-2fd9470edd68.

The Enum.reduce approach in the do_build_query function there illustrates the second step I was confused about.

Anyway, will think some more on this first, and come back if stuck again :slight_smile: