jirutka / rsql-parser

Parser for RSQL / FIQL – query language for RESTful APIs
727 stars 155 forks source link

Support for 'isnull' operator #21

Open aklish opened 8 years ago

aklish commented 8 years ago

Overview

None of the existing operators provide support for testing whether a field is null or conversely is not null.

Technically, such an operator would not require arguments, but the grammar currently requires them:

comparison     = selector, comparator, arguments;
arguments      = ( "(", value, { "," , value }, ")" ) | value;

Here are three suggestions for adding this support:

Option 1

Add new operators:

=isnull=
=notnull=

Change the grammar to allow 0 argument comparisons.

Option 2

Add new operator:

=isnull=

The new operator would take any of the following restricted arguments:

  1. true
  2. false
  3. 0 (0 is the same as false)
  4. 1 (1 is the same as true)

    Option 3

Allow '()' as an argument for operator '==' and '!='. The empty list implicitly means null in these contexts.

kamaydeo commented 8 years ago

I think you can accomplish isNull or isNotNull as follows. isNull: q=title==null isNotNull: q=title!=null

aklish commented 8 years ago

Assuming title is of type String, How do you differentiate between: title==null and title=='null' (the string's value is 'null')?

kamaydeo commented 8 years ago

Yes. There is no way to distinguish between null and 'null'. Ideally, we need a unary operator which is Option1.

aklish commented 8 years ago

I also prefer Option 1, but I'm not sure it agrees with FIQL grammar:

constraint  = selector [ comparison argument ]

Should we relax FIQL compliance and go with the more natural syntax?

ghost commented 8 years ago

I ended up implementing this in our project using the ambiguous 'null' string after bumping into the unary operator issue, but I'm really liking the sound of option 2. It doesn't require messing with the FIQL syntax compliance and can already be implemented by the end-user using a custom operator, plus is inherently backward-compatible since it's just an additional operator(s). The ability to specify true/false for isnull/[is]notnull also allows for a degree of lexical freedom, since you can specify =isnull=false or =[is]notnull=true depending on whichever flavor makes more sense for a given query.

vineey commented 8 years ago

Agree with @chibisoft option 2 is already doable in the existing framework since custom binary operator is already supported, and I think this approach is better to reduce changes on the core library.

aklish commented 8 years ago

I'm fine with option 2. Do we want to make it a default comparison operator - or should this be considered custom? I would imagine default (not custom) would be more useful to others.

Also, I played with option 1 (which has the benefit of shortening the URL). I was able to make relatively minor changes to the grammar if I:

  1. Made the unary operator '=isnull'
  2. Increased the lookahead of the parser to 2 instead of 1.

Is option 1 worth exploring through a PR, or should we just proceed with option 2? If option 2, default or custom? Thanks.

drenda commented 5 years ago

Hi, is this feature already supported? Thanks

mdhtr commented 4 years ago

Just to cross-link: tricolor2 added a pull request for this feature in December 2018. See https://github.com/jirutka/rsql-parser/pull/37

torshid commented 3 years ago

For those asking in 2021, you can check my lightweight library which supports is null, is empty, and/or, bools, enums, dates, searching over relations (joins), and much more here https://github.com/turkraft/spring-filter