Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect comparison #145

Closed
mathursharp opened this issue Oct 26, 2015 · 11 comments
Closed

Incorrect comparison #145

mathursharp opened this issue Oct 26, 2015 · 11 comments
Labels

Comments

@mathursharp
Copy link

I have the following json,

{"store":{"book":[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22}],"bicycle":{"color":"red","price":19}},"ExDataList":[{"key":"numOfPages","value":"2341","timestamp":"08-13-2015 06:32:13"},{"key":"numOfImages","value":"69","timestamp":"08-13-2015 06:32:13"},{"key":"numOfComments","value":"89","timestamp":"08-13-2015 06:32:13"},{"key":"numOfBookmarks","value":"3","timestamp":"08-13-2015 06:32:13"}],"expensive":10}

On the above json, i am trying to evaluate the following jsonpath expression,

$.ExDataList[?(@.key=='numOfImages' && @.value>100)]

Ideally the above expression should return an empty arraylist, however it is returning the following,

[{"key":"numOfImages","value":"69","timestamp":"08-13-2015 06:32:13"}]

But if, i replace the "100" in the jsonexpression with any other value, say 98, then it is returning the correct output.

I am using the latest release of Jayway JsonPath .

@zline
Copy link
Contributor

zline commented Oct 28, 2015

It looks like value attribute is being compared lexicographically, because it's a string in your json.
I don't see in doc what is the correct behavior in this case, IMHO it's implementation-dependent.

@kallestenflo
Copy link
Contributor

Maybe there should be a new option to configure comparison behavior?

@mathursharp
Copy link
Author

Is there any work around for this kind of situation as of now?

@mathursharp
Copy link
Author

I have also tried evaluating this on some online jsonpath evaluators (http://www.jsonquerytool.com/) , but i don't see this issue there.

@zline
Copy link
Contributor

zline commented Oct 30, 2015

@kallestenflo I think option is a good idea. Option which switches between strict and best-effort comparisons.

Strict comparisons always says false if types involved are incompatible.

I'v implemented best-effort comparison in my project using following scheme. First, every value is "interpreted" depending on its content (and cast accordingly): long-like become long, double-like become double, others are strings. Second, I use the following rules (top-down):
for equality check:

type 1 type 2 action
long long long comparison
long or double long or double cast to double, double comparison
string long or double false
long or double string false
string string string comparison

for GT, LT comparisons:

type 1 type 2 action
long long long comparison
string string string comparison
long or double or string long or double or string strings become 0.0, longs being cast to double, double comparison

@mathursharp

Is there any work around for this kind of situation as of now?

If jsons could not be corrected (type of value), then extract entire nodes $.ExDataList[?(@.key=='numOfImages' && @.value)] and perform extra check of value in code.

I have also tried evaluating this on some online jsonpath evaluators (http://www.jsonquerytool.com/) , but i don't see this issue there.

I think json path as a language lacks specification (Goessner's article is quite shallow to be one), and code (which evaluator is) should not be used as a specification.

@jochenberger
Copy link
Contributor

Or should it behave like JavaScript and differentiate between == and ===?

@kallestenflo
Copy link
Contributor

I like that. @jochenberger if you have time could you provide a couple of tests defining your expected behavior? I will try to fix it tonight.

@jochenberger
Copy link
Contributor

Where would I put those tests? Can I test the comparison alone? I'd expect the same semantics as in JavaScript.

0 == 0
0 == 0.0
0 === 0.0
0 == "0"
0 !== "0"
null == `JsonProvider.UNDEFINED`
null !== `JsonProvider.UNDEFINED`
true == 1
false == 0
true !== 1
"" == false
"0" == false
"1" == true
"true" != true

@jochenberger
Copy link
Contributor

However, if we did this consistently, comparisons will become somewhat nasty:

2 < 12 //=> true
2 < "12" //=> true
"2" < 12 //=> true
"2" < "12" //=> false
"12" < "2" //=> true
"foo" < "2" //=> false
"" < 2 //=> true
"foo" > "2" //=> false
(When comparing a string with a number, JavaScript will convert the string to a number when doing the comparison. An empty string converts to 0. A non-numeric string converts to NaN which is always false.)

@zline
Copy link
Contributor

zline commented Dec 4, 2015

@kallestenflo btw, somewhere after 22d8a78 backward-incompatible change was introduced: 1 == '1' used to be true, but now (9258487) its false.

kallestenflo added a commit that referenced this issue Dec 8, 2015
…tring and number. Introduced === and !== to do type safe comparison.
@kallestenflo
Copy link
Contributor

This is fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants