Skip to content

Commit 6454aaf

Browse files
committed
HHH-18496 Add json_exists and support the passing clause
1 parent 016b463 commit 6454aaf

File tree

61 files changed

+1888
-154
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1888
-154
lines changed

documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,6 +1632,7 @@ The following functions deal with SQL JSON types, which are not supported on eve
16321632
| `json_object()` | Constructs a JSON object from pairs of key and value arguments
16331633
| `json_array()` | Constructs a JSON array from arguments
16341634
| `json_value()` | Extracts a value from a JSON document by JSON path
1635+
| `json_exists()` | Checks if a JSON path exists in a JSON document
16351636
|===
16361637
16371638
@@ -1713,7 +1714,8 @@ The first argument is an expression to a JSON document. The second argument is a
17131714
17141715
WARNING: Some databases might also return non-scalar values. Beware that this behavior is not portable.
17151716
1716-
NOTE: It is recommended to only us the dot notation for JSON paths, since most databases support only that.
1717+
NOTE: It is recommended to only us the dot notation for JSON paths instead of the bracket notation,
1718+
since most databases support only that.
17171719
17181720
[[hql-json-value-example]]
17191721
====
@@ -1723,24 +1725,23 @@ include::{json-example-dir-hql}/JsonValueTest.java[tags=hql-json-value-example]
17231725
----
17241726
====
17251727
1726-
The `returning` clause allows to specify the <<hql-function-cast,cast target>> i.e. the type of value to extract.
1728+
The `passing` clause allows to reuse the same JSON path but pass different values for evaluation.
17271729
1728-
[[hql-json-value-returning-example]]
1730+
[[hql-json-value-passing-example]]
17291731
====
17301732
[source, java, indent=0]
17311733
----
1732-
include::{json-example-dir-hql}/JsonValueTest.java[tags=hql-json-value-returning-example]
1734+
include::{json-example-dir-hql}/JsonValueTest.java[tags=hql-json-value-passing-example]
17331735
----
17341736
====
17351737
1736-
The `on empty` clause defines the behavior when the JSON path does not match the JSON document.
1737-
By default, `null` is returned on empty.
1738+
The `returning` clause allows to specify the <<hql-function-cast,cast target>> i.e. the type of value to extract.
17381739
1739-
[[hql-json-value-on-error-example]]
1740+
[[hql-json-value-returning-example]]
17401741
====
17411742
[source, java, indent=0]
17421743
----
1743-
include::{json-example-dir-hql}/JsonValueTest.java[tags=hql-json-value-on-error-example]
1744+
include::{json-example-dir-hql}/JsonValueTest.java[tags=hql-json-value-returning-example]
17441745
----
17451746
====
17461747
@@ -1754,6 +1755,17 @@ Conditions that classify as errors are database dependent, but usual errors whic
17541755
The default behavior of `on error` is database specific, but usually, `null` is returned on an error.
17551756
It is recommended to specify this clause when the exact error behavior is important.
17561757
1758+
[[hql-json-value-on-error-example]]
1759+
====
1760+
[source, java, indent=0]
1761+
----
1762+
include::{json-example-dir-hql}/JsonValueTest.java[tags=hql-json-value-on-error-example]
1763+
----
1764+
====
1765+
1766+
The `on empty` clause defines the behavior when the JSON path does not match the JSON document.
1767+
By default, `null` is returned on empty.
1768+
17571769
[[hql-json-value-on-empty-example]]
17581770
====
17591771
[source, java, indent=0]
@@ -1767,6 +1779,59 @@ Depending on the database, an error might still be thrown even without that, but
17671779
17681780
NOTE: The H2 emulation only supports absolute JSON paths using the dot notation.
17691781
1782+
[[hql-json-exists-function]]
1783+
===== `json_exists()`
1784+
1785+
Checks if a JSON document contains a https://www.ietf.org/archive/id/draft-goessner-dispatch-jsonpath-00.html[JSON path].
1786+
1787+
[[hql-json-exists-bnf]]
1788+
[source, antlrv4, indent=0]
1789+
----
1790+
include::{extrasdir}/json_exists_bnf.txt[]
1791+
----
1792+
1793+
The first argument is an expression to a JSON document. The second argument is a JSON path as String expression.
1794+
1795+
NOTE: It is recommended to only us the dot notation for JSON paths instead of the bracket notation,
1796+
since most databases support only that.
1797+
1798+
[[hql-json-exists-example]]
1799+
====
1800+
[source, java, indent=0]
1801+
----
1802+
include::{json-example-dir-hql}/JsonExistsTest.java[tags=hql-json-exists-example]
1803+
----
1804+
====
1805+
1806+
The `passing` clause allows to reuse the same JSON path but pass different values for evaluation.
1807+
1808+
[[hql-json-exists-passing-example]]
1809+
====
1810+
[source, java, indent=0]
1811+
----
1812+
include::{json-example-dir-hql}/JsonExistsTest.java[tags=hql-json-exists-passing-example]
1813+
----
1814+
====
1815+
1816+
The `on error` clause defines the behavior when an error occurs while checking for existence with the JSON path.
1817+
Conditions that classify as errors are database dependent, but usual errors which can be handled with this clause are:
1818+
1819+
* First argument is not a valid JSON document
1820+
* Second argument is not a valid JSON path
1821+
1822+
The default behavior of `on error` is database specific, but usually, `false` is returned on an error.
1823+
It is recommended to specify this clause when the exact error behavior is important.
1824+
1825+
[[hql-json-exists-on-error-example]]
1826+
====
1827+
[source, java, indent=0]
1828+
----
1829+
include::{json-example-dir-hql}/JsonExistsTest.java[tags=hql-json-exists-on-error-example]
1830+
----
1831+
====
1832+
1833+
NOTE: The H2 emulation only supports absolute JSON paths using the dot notation.
1834+
17701835
[[hql-user-defined-functions]]
17711836
==== Native and user-defined functions
17721837
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"json_exists(" expression, expression passingClause? onErrorClause? ")"
2+
3+
passingClause
4+
: "passing" expression "as" identifier ("," expression "as" identifier)*
5+
6+
onErrorClause
7+
: ( "error" | "true" | "false" ) "on error";

documentation/src/main/asciidoc/userguide/chapters/query/hql/extras/json_value_bnf.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
"json_value(" expression, expression ("returning" castTarget)? onErrorClause? onEmptyClause? ")"
1+
"json_value(" expression, expression passingClause? ("returning" castTarget)? onErrorClause? onEmptyClause? ")"
2+
3+
passingClause
4+
: "passing" expression "as" identifier ("," expression "as" identifier)*
25

36
onErrorClause
47
: ( "error" | "null" | ( "default" expression ) ) "on error";

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
503503

504504
functionFactory.jsonValue_cockroachdb();
505505
functionFactory.jsonObject_postgresql();
506+
functionFactory.jsonExists_postgresql();
506507
functionFactory.jsonArray_postgresql();
507508

508509
// Postgres uses # instead of ^ for XOR

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacyDialect.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,8 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
431431
functionFactory.listagg( null );
432432

433433
if ( getDB2Version().isSameOrAfter( 11 ) ) {
434-
functionFactory.jsonValue();
434+
functionFactory.jsonValue_no_passing();
435+
functionFactory.jsonExists_no_passing();
435436
functionFactory.jsonObject_db2();
436437
functionFactory.jsonArray_db2();
437438
}

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacyDialect.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
404404

405405
if ( getVersion().isSameOrAfter( 2, 2, 220 ) ) {
406406
functionFactory.jsonValue_h2();
407+
functionFactory.jsonExists_h2();
407408
}
408409
}
409410
else {

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacyDialect.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
654654

655655
if ( getMySQLVersion().isSameOrAfter( 5, 7 ) ) {
656656
functionFactory.jsonValue_mysql();
657+
functionFactory.jsonExists_mysql();
657658
functionFactory.jsonObject_mysql();
658659
functionFactory.jsonArray_mysql();
659660
}

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,8 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
322322
functionFactory.arrayToString_oracle();
323323

324324
if ( getVersion().isSameOrAfter( 12 ) ) {
325-
functionFactory.jsonValue_literal_path();
325+
functionFactory.jsonValue_oracle();
326+
functionFactory.jsonExists_oracle();
326327
functionFactory.jsonObject_oracle();
327328
functionFactory.jsonArray_oracle();
328329
}

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,11 +634,13 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
634634

635635
if ( getVersion().isSameOrAfter( 17 ) ) {
636636
functionFactory.jsonValue();
637+
functionFactory.jsonExists();
637638
functionFactory.jsonObject();
638639
functionFactory.jsonArray();
639640
}
640641
else {
641642
functionFactory.jsonValue_postgresql();
643+
functionFactory.jsonExists_postgresql();
642644
if ( getVersion().isSameOrAfter( 16 ) ) {
643645
functionFactory.jsonObject();
644646
functionFactory.jsonArray();

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacyDialect.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
402402
functionFactory.hypotheticalOrderedSetAggregates_windowEmulation();
403403
if ( getVersion().isSameOrAfter( 13 ) ) {
404404
functionFactory.jsonValue_sqlserver();
405+
functionFactory.jsonExists_sqlserver();
405406
functionFactory.jsonObject_sqlserver();
406407
functionFactory.jsonArray_sqlserver();
407408
}

0 commit comments

Comments
 (0)