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

JSON + whereNull/whereNotNull is non-intuitive or broken #31473

Closed
LastDragon-ru opened this issue Feb 14, 2020 · 8 comments · Fixed by #32417
Closed

JSON + whereNull/whereNotNull is non-intuitive or broken #31473

LastDragon-ru opened this issue Feb 14, 2020 · 8 comments · Fixed by #32417
Labels

Comments

@LastDragon-ru
Copy link
Contributor

LastDragon-ru commented Feb 14, 2020

  • Laravel Version: 5.8 / 6.x
  • PHP Version: 7.2.0
  • Database Driver & Version: MySQL 5.7 (not sure about other dbs)

Description:

The whereNull('a->b') will generate json_unquote(json_extract(`a`, '$."b"')) is null that doesn't work as expected:

set @a='{"a":3,"b":null}';

select 
json_unquote(json_extract(@a, '$."b"')) IS NULL, -- = false (but value is null => should be true)
json_unquote(json_extract(@a, '$."c"')) IS NULL; -- = true

image

Desired behavior:

  1. IMHO whereNull should cover both cases:
    1. key doesn't exist (fine now)
    2. key exists but the value is null (the JSON_TYPE(json_extract(@a, '$."b"')) = 'NULL' can be used)
  2. (or) will be probably good to have a notice in docs about this non-intuitive whereNull behavior.

Also, this issue similar to #27696

@driesvints
Copy link
Member

@staudenmeir since you sent in #27847 can you maybe weigh in here? Thanks.

@staudenmeir
Copy link
Contributor

I'll look into it.

@Krunch
Copy link

Krunch commented Feb 17, 2020

If you want more information on this, there is a MySQL bug on this exact subject (JSON not returning SQL NULL in some cases). This is a distinct behavior in MySQL and I haven't seen this in other SQL engines.

https://bugs.mysql.com/bug.php?id=85755

Edit: This also applies to boolean values, JSON functions inside MySQL does not return a SQL boolean type for those either.

@driesvints
Copy link
Member

Closing this since this is a MySQL bug.

@LastDragon-ru
Copy link
Contributor Author

LastDragon-ru commented Apr 16, 2020

Closing this since this is a MySQL bug.

@driesvints, this is not a bug in general, please read mysql.com carefully - this is special behavior to distinguish when key exists and when not (same as isset and array_key_exists). And Laravel must handle this properly. Please reopen.

@driesvints
Copy link
Member

@LastDragon-ru can you point to the parts where it says that?

@Krunch
Copy link

Krunch commented Apr 16, 2020

@driesvints https://bugs.mysql.com/bug.php?id=85755 (2nd reply)

[10 Apr 2017 7:09] Knut Anders Hatlen
Posted by developer:

Hi Dave,

I think what you are seeing is the intended behaviour.

JSON_OBJECT('a', NULL) evaluates to the JSON document { "a" : null }. Here, JSON_OBJECT has converted the SQL NULL value to the JSON null literal, which are different in SQL. When you call JSON_EXTRACT with path $.a on { "a" : null }, it extracts the JSON null literal from that document. If JSON_EXTRACT had not found anything on the specified path, it would have returned SQL NULL instead. So the difference between SQL NULL and the JSON null literal allows you do distinguish between the case where JSON_EXTRACT found a (JSON) null value and the case where it didn't find anything.

I didn't find any mentioning of how JSON_OBJECT handles NULL values in the reference manual, only in the design documents for WL#7909 which added the JSON_OBJECT function. Unless I have overlooked something in the manual, maybe what we should do is clarify how JSON_OBJECT handles NULL arguments in the manual.

@driesvints
Copy link
Member

Gotcha thanks. Feel free to send in a PR for this.

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

Successfully merging a pull request may close this issue.

4 participants