jirutka/rsql-parser

Support for 'isnull' operator

Opened this issue · 10 comments

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.

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

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

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

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?

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.

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.

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.

Hi,
is this feature already supported? Thanks

mdhtr commented

Just to cross-link: tricolor2 added a pull request for this feature in December 2018. See #37

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