[MDEV-23143] Add JSON_EQUALS function to check JSON equality Created: 2020-07-10  Updated: 2023-11-27  Resolved: 2021-09-12

Status: Closed
Project: MariaDB Server
Component/s: JSON
Fix Version/s: 10.7.0

Type: Task Priority: Major
Reporter: Eric Herman Assignee: Vicențiu Ciorbaru
Resolution: Fixed Votes: 2
Labels: JSON, beginner-friendly, gsoc21

Issue Links:
Problem/Incident
causes MDEV-26678 JSON_EQUALS validates invalid JSON an... Closed
Relates
relates to MDEV-16375 Add JSON_NORMALIZE function to normal... Closed

 Description   

JSON_CONTAINS can be used to test for JSON object equality in some cases, but we seem to lack a clear JSON_EQUALS function.



 Comments   
Comment by Eric Herman [ 2020-07-10 ]

MariaDB [test]> show create table foo\G
*************************** 1. row ***************************
       Table: foo
Create Table: CREATE TABLE `foo` (
  `foo_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `foo_dat` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`foo_dat`)),
  PRIMARY KEY (`foo_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
1 row in set (0.000 sec)
 
MariaDB [test]> SELECT * FROM foo;
+--------+--------------------------+
| foo_id | foo_dat                  |
+--------+--------------------------+
|      1 | {"A": 1, "C": 3, "B": 2} |
|      2 | {"A": 7, "C": 9, "B": 8} |
+--------+--------------------------+
2 rows in set (0.000 sec)
 
MariaDB [test]> SELECT * FROM foo WHERE JSON_CONTAINS(foo_dat, '{"A": 1, "B": 2, "C": 3}');
+--------+--------------------------+
| foo_id | foo_dat                  |
+--------+--------------------------+
|      1 | {"A": 1, "C": 3, "B": 2} |
+--------+--------------------------+
1 row in set (0.000 sec)

Thank you @Kartik Soneji , this was non-obvious to me from the https://mariadb.com/kb/en/json-functions/ page.

While JSON_CONTAINS can work, to avoid matching larger objects we probably want two comparisons, e.g.::

MariaDB [test]> SELECT foo_id FROM foo WHERE
    ->      JSON_CONTAINS(foo_dat, '{"A": 1, "B": 2, "C": 3}')
    ->  AND JSON_CONTAINS('{"A": 1, "B": 2, "C": 3}', foo_dat);
+--------+
| foo_id |
+--------+
|      1 |
+--------+
1 row in set (0.000 sec)

I feel like a more explicit JSON_EQUALS is still desired.

It looks like fairly common problem:
https://stackoverflow.com/questions/59471116/mariadb-compare-two-json-objects
https://stackoverflow.com/questions/46734547/compare-json-values-in-mariadb
https://dba.stackexchange.com/questions/208481/mariadb-compare-json

Comment by Rodrigo Souza [ 2020-10-03 ]

@Daniel Black I wonder if would be OK for me to take this task?

Do we have anybody to talk about it and get advices?

Comment by LiuYuJi [ 2021-03-20 ]

Hello, I am Liu Yuji, I have studied C/C++ programming and SQL and JSON. I would like to work on this project in GSOC 2021, and I have installed MariaDB and MariaDB's source code on my system. Hope someone can give me some guidance, I would be very grateful for that.

Comment by Roel Van de Paar [ 2021-09-25 ]

Logged MDEV-26678 JSON_EQUALS validates invalid JSON and valid JSON as being equal when using a backslash
Also logged mostly unrelated MDEV-26679 JSON_VALID validates invalid JSON

Generated at Thu Feb 08 09:20:10 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.