Skip to content

Commit

Permalink
LITE-30338: Including 2 new terms to be able to parse logical and tup…
Browse files Browse the repository at this point in the history
…le terms inside braces.
  • Loading branch information
akodelia committed Jun 13, 2024
1 parent 1d46965 commit 5a21130
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 11 deletions.
22 changes: 12 additions & 10 deletions py_rql/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,28 @@

RQL_GRAMMAR = r"""
start: _top_term?
_top_term: term
| term_and_comma
term: expr_term
| logical
| tuple
| _L_BRACE logical _R_BRACE
| _L_BRACE tuple _R_BRACE
expr_term: comp
| listing
| searching
| ordering
| select
| _L_BRACE expr_term _R_BRACE
logical: and_op
| or_op
| not_op
and_op: _and
and_op: _and
| _L_BRACE _and _R_BRACE
_and: _AND? _logical_exp
Expand All @@ -57,15 +59,15 @@
comp: comp_term _L_BRACE prop _COMMA val _R_BRACE
| prop _EQUALITY comp_term _EQUALITY val
| prop _EQUALITY val
listing: list_term _L_BRACE prop _COMMA _L_BRACE val (_COMMA val)* _R_BRACE _R_BRACE
searching: search_term _L_BRACE prop _COMMA val _R_BRACE
ordering: ordering_term _signed_props
select: select_term _signed_props
_signed_props: _L_BRACE _R_BRACE
| _L_BRACE sign_prop (_COMMA sign_prop)* _R_BRACE
val: prop
| tuple
| QUOTED_VAL
Expand All @@ -78,19 +80,19 @@
| ordering_term
| select_term
| PROP
tuple: _TUPLE _L_BRACE (comp|searching) (_COMMA (comp|searching))* _R_BRACE
!sign_prop: ["+"|"-"] prop
!comp_term: "eq" | "ne" | "gt" | "ge" | "lt" | "le"
!logical_term: _AND | _OR | _NOT
!list_term: "in" | "out"
!search_term: "like" | "ilike"
!ordering_term: "ordering"
!select_term: "select"
PROP: /[a-zA-Z]/ /[\w\-\.]/*
QUOTED_VAL: /"[^"]*"/
| /'[^']*'/
Expand Down
51 changes: 50 additions & 1 deletion tests/test_parser/test_logical.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
import pytest
from lark.exceptions import LarkError

from py_rql.constants import ComparisonOperators, LogicalOperators
from py_rql.constants import (
ComparisonOperators,
LogicalOperators,
SearchOperators,
)
from py_rql.parser import RQLParser
from tests.test_parser.utils import LogicalTransformer

Expand Down Expand Up @@ -199,3 +203,48 @@ def test_or_chain(query):
(ComparisonOperators.EQ, 'p4', 'v4'),
],
}


def test_logical_tuple_and_not():
result = logical_transform('(not(id=fg))')

not_grammar_key = LogicalOperators.get_grammar_key(LogicalOperators.NOT)

assert result == {
not_grammar_key: [(ComparisonOperators.EQ, 'id', 'fg')],
}


def test_logical_tuple_and_not_w_and_nesting():
result = logical_transform('((not(eq(id,fg)))&(not(ge(external_id,fg))))')

and_grammar_key = LogicalOperators.get_grammar_key(LogicalOperators.AND)
not_grammar_key = LogicalOperators.get_grammar_key(LogicalOperators.NOT)

assert result == {
and_grammar_key: [
{not_grammar_key: [(ComparisonOperators.EQ, 'id', 'fg')]},
{not_grammar_key: [(ComparisonOperators.GE, 'external_id', 'fg')]}
]
}


def test_logical_tuple_nesting_ands_and_ors():
result = logical_transform(
'((((eq(id,*baba*))&(eq(external_id,*baba*))))|(((eq(id,*dziad*)))))',
)

and_grammar_key = LogicalOperators.get_grammar_key(LogicalOperators.AND)
or_grammar_key = LogicalOperators.get_grammar_key(LogicalOperators.OR)

assert result == {
or_grammar_key: [
{
and_grammar_key: [
(ComparisonOperators.EQ, 'id', '*baba*'),
(ComparisonOperators.EQ, 'external_id', '*baba*')
]
},
(ComparisonOperators.EQ, 'id', '*dziad*')
]
}

0 comments on commit 5a21130

Please sign in to comment.