bitovi / querystring-parser

MIT License
8 stars 5 forks source link

Unable to parse filter when the string contains : - , + , _ , * or any num alpha numerical sign. #83

Open noyessie opened 3 months ago

noyessie commented 3 months ago

Here is the query I tried with

ps = qps.parse("filter=and(any('value','53','54','269','55','56','62','70','73','100'),any('userId','2','2:63'))")
# response { orm: 'sequelize', data: {}, errors: [] }

If I remove the options '2:63', it works fine. what is the issue please.

michael-dean-haynie commented 2 months ago

Hey @noyessie - thanks for opening this issue :)

Few things to note after some investigation:

1. Incorrect syntax In your example above you've got single quotes around the field/attribute names which is incorrect. For example, this sub-expression any('userId','2','2:63') should be any(userId,'2','2:63') (note the lack of quotes around userId

There are some more examples on the readme that illustrate this point: https://github.com/bitovi/querystring-parser/blob/main/packages/querystring-parser/README.md#quick-examples-1

WHY the field names need to not have quotes ... because the IBM-style filtering was based on https://www.jsonapi.net/usage/reading/filtering.html and that's how they do it. I'm not sure exactly sure why, probably to distinguish field references from constant values. But perhaps the position of the field reference in the expression is enough. We might be able to support quoted field references ... not sure. Will take additional investigation.

But as for THIS issue, you can probably address this point by simply unquoting those field references like in the example above.

2. Type coercion / multiple types in any expression The any() operator is not supposed to be used with multiple value types. For example: any(name, 'beth', '2.5') In general it doesn't make sense that a field could match both a string and a number. It should be either/or. (The quotes around 2.5 don't make it a string, they make it a constant value as opposed to a field reference)

So in your example: any('userId','2','2:63') The '2' is being coerced into a number and '2:63' is being treated as a string.

Maybe the multiple types restriction can/should be relaxed. Maybe there should be a more explicit way to express constant value types. Cause right now there seems to be no way to filter with a constant value of, say, the string "2". It will always get interpreted as a number and coerced as such.

We can see the issue here: https://github.com/bitovi/querystring-parser/blob/a5252d07ee01cf6d9ad6539328baaed0d1ede793/packages/querystring-parser/lib/filter-styles/parse-ibm-filter.js#L117-L138

3. Errors are empty? In any case you should be seeing errors in the error array of the response. I was not able to reproduce the missing errors. When I ran the code in a unit test I got descriptive errors about the multiple types restriction. Will have to investigate that further.

michael-dean-haynie commented 2 months ago

Might also be worth exploring a minimal effort solution that allows escape sequences. That way you explicitly make it a string by wrapping values in escaped quotes.