简体   繁体   中英

Parser for Expression Filter

I have table column with expression filter applied. Is there any existing parser that would allow me to parse this column? the column can contain simple conditions such as

PROPERTY = 'name' AND PROPERTY2 = 'something else'

or more advanced like

(PROPERTY IN ('foo', 'bar') 
  AND (PROPERTY IN ('foo1', 'bar2') OR OTHER_PROPERTY IN ('etc'))

It would totally suffice if it would return list of properties in expression and either value (in case of = operator) or list of all values (even if one property appears more than once in expression). Is there such parser available or do I have to write it myself?

I don't know how you are developing your project. But if your are using hibernate you can use criteria queries. Cirteria queries

You could usejOOQ's parser . Given this requirement:

It would totally suffice if it would return list of properties in expression and either value (in case of = operator) or list of all values (even if one property appears more than once in expression)

You could run this piece of code:

Map<Field<?>, List<QueryPart>> result =
DSL.using(SQLDialect.DEFAULT)
   .parser()
   // Parse the SQL string to a jOOQ expression tree
   .parseCondition(
       """
       (PROPERTY IN ('foo', 'bar')
           AND (PROPERTY IN ('foo1', 'bar2') OR OTHER_PROPERTY IN ('etc')))
       """)
   // Traverse the jOOQ expression tree using Traversers and Collectors
   // You can also traverse the tree using imperative APIs, of course
   .$traverse(Traversers.collecting(
       Collectors.filtering(p -> p instanceof InList 
                              || p instanceof CompareCondition,
           Collectors.groupingBy(p ->
                 p instanceof InList<?> i
               ? i.$arg1()
               : p instanceof CompareCondition<?> c
               ? c.$arg1()
               : null,
               Collectors.mapping(p ->
                     p instanceof InList<?> i
                   ? i.$arg2()
                   : p instanceof CompareCondition<?> c
                   ? c.$arg2()
                   : null,
                   Collectors.toList()
               )
           )
       )
   ));
System.out.println(result);

It produces this output:

{PROPERTY=['foo', 'bar', 'foo1', 'bar2'], OTHER_PROPERTY=['etc']}

Not sure if this exactly matches your requirements, but it should be straightforward to tweak the code accordingly

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM