Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
:example-dir-hql: {core-project-dir}/src/test/java/org/hibernate/orm/test/hql
:array-example-dir-hql: {core-project-dir}/src/test/java/org/hibernate/orm/test/function/array
:json-example-dir-hql: {core-project-dir}/src/test/java/org/hibernate/orm/test/function/json
:xml-example-dir-hql: {core-project-dir}/src/test/java/org/hibernate/orm/test/function/xml
:extrasdir: extras

This chapter describes Hibernate Query Language (HQL) and Jakarta Persistence Query Language (JPQL).
Expand Down Expand Up @@ -2158,6 +2159,222 @@ include::{json-example-dir-hql}/JsonArrayInsertTest.java[tags=hql-json-array-ins

WARNING: SAP HANA, DB2, H2 and HSQLDB do not support this function.

[[hql-functions-xml]]
==== Functions for dealing with XML

The following functions deal with SQL XML types, which are not supported on every database.

NOTE: The following functions are incubating/tech-preview and to use them in HQL,
it is necessary to enable the `hibernate.query.hql.xml_functions_enabled` configuration setting.

[[hql-xml-functions]]
|===
| Function | Purpose

| `xmlelement()` | Constructs an XML element from arguments
| `xmlcomment()` | Constructs an XML comment from the single argument
| `xmlforest()` | Constructs an XML forest from the arguments
| `xmlconcat()` | Concatenates multiple XML fragments to each other
| `xmlpi()` | Constructs an XML processing instruction
| `xmlquery()` | Extracts content from XML document using XQuery or XPath
| `xmlexists()` | Checks if an XQuery or XPath expression exists in an XML document
| `xmlagg()` | Aggregates XML elements by concatenation
|===


[[hql-xmlelement-function]]
===== `xmlelement()`

Constructs an XML element from the arguments.

[[hql-xmlelement-bnf]]
[source, antlrv4, indent=0]
----
include::{extrasdir}/xmlelement_bnf.txt[]
----

The identifier represents the XML element name and can be quoted by using backticks.

[[hql-xmlelement-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlElementTest.java[tags=hql-xmlelement-example]
----
====

XML element attributes can be defined by using the `xmlattributes` function as second argument.
All following arguments represent the XML content.

[[hql-xmlelement-attributes-content-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlElementTest.java[tags=hql-xmlelement-attributes-content-example]
----
====

WARNING: SAP HANA, MySQL, MariaDB and HSQLDB do not support this function.

[[hql-xmlcomment-function]]
===== `xmlcomment()`

Constructs an XML comment from the single string argument.

[[hql-xmlcomment-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlCommentTest.java[tags=hql-xmlcomment-example]
----
====

WARNING: SAP HANA, MySQL, MariaDB and HSQLDB do not support this function.

[[hql-xmlforest-function]]
===== `xmlforest()`

Constructs an XML forest from the arguments. A forest is a sequence of XML elements.

[[hql-xmlforest-bnf]]
[source, antlrv4, indent=0]
----
include::{extrasdir}/xmlforest_bnf.txt[]
----

The optional name specifies the XML element name to use for the content as produced by the expression.
The name can be omitted if a path expression is passed, in which case the last attribute name is used as element name.

[[hql-xmlforest-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlForestTest.java[tags=hql-xmlforest-example]
----
====

WARNING: SAP HANA, MySQL, MariaDB and HSQLDB do not support this function.

[[hql-xmlconcat-function]]
===== `xmlconcat()`

Concatenates multiple XML fragments to each other.

[[hql-xmlconcat-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlConcatTest.java[tags=hql-xmlconcat-example]
----
====

WARNING: SAP HANA, MySQL, MariaDB and HSQLDB do not support this function.

[[hql-xmlpi-function]]
===== `xmlpi()`

Constructs an XML processing instruction from the arguments.

[[hql-xmlpi-bnf]]
[source, antlrv4, indent=0]
----
include::{extrasdir}/xmlpi_bnf.txt[]
----

The identifier represents the XML processing instruction name and can be quoted by using backticks.

[[hql-xmlpi-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlPiTest.java[tags=hql-xmlpi-example]
----
====

The optional second argument represents the processing instruction content.

[[hql-xmlpi-content-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlPiTest.java[tags=hql-xmlpi-content-example]
----
====

WARNING: SAP HANA, MySQL, MariaDB and HSQLDB do not support this function.

[[hql-xmlquery-function]]
===== `xmlquery()`

Extracts content from an XML document using XQuery or XPath.

[[hql-xmlquery-bnf]]
[source, antlrv4, indent=0]
----
include::{extrasdir}/xmlquery_bnf.txt[]
----

The first argument represents the XQuery or XPath expression.
The second argument after the `passing` keyword represents the XML document.

[[hql-xmlquery-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlQueryTest.java[tags=hql-xmlquery-example]
----
====

WARNING: SAP HANA, MySQL, MariaDB and HSQLDB do not support this function.

[[hql-xmlexists-function]]
===== `xmlexists()`

Checks if an XQuery or XPath expression exists in an XML document.

[[hql-xmlexists-bnf]]
[source, antlrv4, indent=0]
----
include::{extrasdir}/xmlexists_bnf.txt[]
----

The first argument represents the XQuery or XPath expression.
The second argument after the `passing` keyword represents the XML document.

[[hql-xmlexists-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlExistsTest.java[tags=hql-xmlexists-example]
----
====

WARNING: SAP HANA, MySQL, MariaDB and HSQLDB do not support this function.

[[hql-xmlagg-function]]
===== `xmlagg()`

Aggregates XML elements by concatenation.

[[hql-xmlexists-bnf]]
[source, antlrv4, indent=0]
----
include::{extrasdir}/xmlagg_bnf.txt[]
----

This aggregate function is similar to an <<hql-aggregate-functions-orderedset,_ordered set aggregate function_>>
since it allows to specify the order in which elements are aggregated, but uses a special syntax.

[[hql-xmlagg-example]]
====
[source, java, indent=0]
----
include::{xml-example-dir-hql}/XmlAggTest.java[tags=hql-xmlagg-example]
----
====

WARNING: SAP HANA, MySQL, MariaDB and HSQLDB do not support this function.

[[hql-user-defined-functions]]
==== Native and user-defined functions

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"xmlagg(" expression orderByClause? ")" filterClause? overClause?
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"xmlelement(name " identifier xmlattributes? ("," expressionOrPredicate)* ")"

xmlattributes
: "xmlattributes(" expressionOrPredicate " as " identifier ("," expressionOrPredicate " as " identifier)* ")"
;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"xmlexists(" expression "passing" expression ")"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"xmlforest(expressionOrPredicate ("as" identifier)? ("," expressionOrPredicate ("as" identifier)?)* ")"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"xmlpi(name " identifier ("," expressionOrPredicate)? ")"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"xmlquery(" expression "passing" expression ")"
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,21 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
functionFactory.jsonObjectAgg_db2();
}
}

functionFactory.xmlelement();
functionFactory.xmlcomment();
functionFactory.xmlforest();
functionFactory.xmlconcat();
functionFactory.xmlpi();
if ( getDB2Version().isSameOrAfter( 11 ) ) {
functionFactory.xmlquery_db2();
functionFactory.xmlexists();
}
else {
functionFactory.xmlquery_db2_legacy();
functionFactory.xmlexists_db2_legacy();
}
functionFactory.xmlagg();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
// Use group_concat until 2.x as listagg was buggy
functionFactory.listagg_groupConcat();
}

functionFactory.xmlelement_h2();
functionFactory.xmlcomment();
functionFactory.xmlforest_h2();
functionFactory.xmlconcat_h2();
functionFactory.xmlpi_h2();
}
else {
functionFactory.listagg_groupConcat();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,15 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
functionFactory.jsonArrayAppend_oracle();
functionFactory.jsonArrayInsert_oracle();
}

functionFactory.xmlelement();
functionFactory.xmlcomment();
functionFactory.xmlforest();
functionFactory.xmlconcat();
functionFactory.xmlpi();
functionFactory.xmlquery_oracle();
functionFactory.xmlexists();
functionFactory.xmlagg();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,15 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
functionFactory.jsonArrayAppend_postgresql( getVersion().isSameOrAfter( 13 ) );
functionFactory.jsonArrayInsert_postgresql();

functionFactory.xmlelement();
functionFactory.xmlcomment();
functionFactory.xmlforest();
functionFactory.xmlconcat();
functionFactory.xmlpi();
functionFactory.xmlquery_postgresql();
functionFactory.xmlexists();
functionFactory.xmlagg();

if ( getVersion().isSameOrAfter( 9, 4 ) ) {
functionFactory.makeDateTimeTimestamp();
// Note that PostgreSQL doesn't support the OVER clause for ordered set-aggregate functions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,14 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
functionFactory.jsonArrayAppend_sqlserver( getVersion().isSameOrAfter( 16 ) );
functionFactory.jsonArrayInsert_sqlserver();
}
functionFactory.xmlelement_sqlserver();
functionFactory.xmlcomment_sqlserver();
functionFactory.xmlforest_sqlserver();
functionFactory.xmlconcat_sqlserver();
functionFactory.xmlpi_sqlserver();
functionFactory.xmlquery_sqlserver();
functionFactory.xmlexists_sqlserver();
functionFactory.xmlagg_sqlserver();
if ( getVersion().isSameOrAfter( 14 ) ) {
functionFactory.listagg_stringAggWithinGroup( "varchar(max)" );
functionFactory.jsonArrayAgg_sqlserver( getVersion().isSameOrAfter( 16 ) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ MINELEMENT : [mM] [iI] [nN] [eE] [lL] [eE] [mM] [eE] [nN] [tT];
MININDEX : [mM] [iI] [nN] [iI] [nN] [dD] [eE] [xX];
MINUTE : [mM] [iI] [nN] [uU] [tT] [eE];
MONTH : [mM] [oO] [nN] [tT] [hH];
NAME : [nN] [aA] [mM] [eE];
NANOSECOND : [nN] [aA] [nN] [oO] [sS] [eE] [cC] [oO] [nN] [dD];
NEW : [nN] [eE] [wW];
NEXT : [nN] [eE] [xX] [tT];
Expand Down Expand Up @@ -329,6 +330,13 @@ WITH : [wW] [iI] [tT] [hH];
WITHIN : [wW] [iI] [tT] [hH] [iI] [nN];
WITHOUT : [wW] [iI] [tT] [hH] [oO] [uU] [tT];
WRAPPER : [wW] [rR] [aA] [pP] [pP] [eE] [rR];
XMLAGG : [xX] [mM] [lL] [aA] [gG] [gG];
XMLATTRIBUTES : [xX] [mM] [lL] [aA] [tT] [tT] [rR] [iI] [bB] [uU] [tT] [eE] [sS];
XMLELEMENT : [xX] [mM] [lL] [eE] [lL] [eE] [mM] [eE] [nN] [tT];
XMLEXISTS : [xX] [mM] [lL] [eE] [xX] [iI] [sS] [tT] [sS];
XMLFOREST : [xX] [mM] [lL] [fF] [oO] [rR] [eE] [sS] [tT];
XMLPI : [xX] [mM] [lL] [pP] [iI];
XMLQUERY : [xX] [mM] [lL] [qQ] [uU] [eE] [rR] [yY];
YEAR : [yY] [eE] [aA] [rR];
ZONED : [zZ] [oO] [nN] [eE] [dD];

Expand Down
Loading
Loading