diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java index 27919427a0..81ec897ce9 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java @@ -512,8 +512,9 @@ public class CockroachLegacyDialect extends Dialect { functionFactory.jsonRemove_cockroachdb(); functionFactory.jsonReplace_postgresql(); functionFactory.jsonInsert_postgresql(); - functionFactory.jsonMergepatch_postgresql(); - functionFactory.jsonArrayAppend_postgresql(); + // No support for WITH clause in subquery: https://github.com/cockroachdb/cockroach/issues/131011 +// functionFactory.jsonMergepatch_postgresql(); + functionFactory.jsonArrayAppend_postgresql( false ); functionFactory.jsonArrayInsert_postgresql(); // Postgres uses # instead of ^ for XOR diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java index 291300bab7..6dc5e338ff 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java @@ -662,8 +662,11 @@ public class PostgreSQLLegacyDialect extends Dialect { functionFactory.jsonRemove_postgresql(); functionFactory.jsonReplace_postgresql(); functionFactory.jsonInsert_postgresql(); - functionFactory.jsonMergepatch_postgresql(); - functionFactory.jsonArrayAppend_postgresql(); + if ( getVersion().isSameOrAfter( 13 ) ) { + // Requires support for WITH clause in subquery which only 13+ provides + functionFactory.jsonMergepatch_postgresql(); + } + functionFactory.jsonArrayAppend_postgresql( getVersion().isSameOrAfter( 13 ) ); functionFactory.jsonArrayInsert_postgresql(); if ( getVersion().isSameOrAfter( 9, 4 ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java index 93bc7b5eb0..5e7dee6227 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java @@ -479,8 +479,9 @@ public class CockroachDialect extends Dialect { functionFactory.jsonRemove_cockroachdb(); functionFactory.jsonReplace_postgresql(); functionFactory.jsonInsert_postgresql(); - functionFactory.jsonMergepatch_postgresql(); - functionFactory.jsonArrayAppend_postgresql(); + // No support for WITH clause in subquery: https://github.com/cockroachdb/cockroach/issues/131011 +// functionFactory.jsonMergepatch_postgresql(); + functionFactory.jsonArrayAppend_postgresql( false ); functionFactory.jsonArrayInsert_postgresql(); // Postgres uses # instead of ^ for XOR diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java index 17b7d0b562..e7900ad373 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java @@ -623,8 +623,11 @@ public class PostgreSQLDialect extends Dialect { functionFactory.jsonRemove_postgresql(); functionFactory.jsonReplace_postgresql(); functionFactory.jsonInsert_postgresql(); - functionFactory.jsonMergepatch_postgresql(); - functionFactory.jsonArrayAppend_postgresql(); + if ( getVersion().isSameOrAfter( 13 ) ) { + // Requires support for WITH clause in subquery which only 13+ provides + functionFactory.jsonMergepatch_postgresql(); + } + functionFactory.jsonArrayAppend_postgresql( getVersion().isSameOrAfter( 13 ) ); functionFactory.jsonArrayInsert_postgresql(); functionFactory.makeDateTimeTimestamp(); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java index a3d2e63062..8de8aeadf9 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java @@ -4018,8 +4018,8 @@ public class CommonFunctionFactory { /** * PostgreSQL json_array_append() function */ - public void jsonArrayAppend_postgresql() { - functionRegistry.register( "json_array_append", new PostgreSQLJsonArrayAppendFunction( typeConfiguration ) ); + public void jsonArrayAppend_postgresql(boolean supportsLax) { + functionRegistry.register( "json_array_append", new PostgreSQLJsonArrayAppendFunction( supportsLax, typeConfiguration ) ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/json/PostgreSQLJsonArrayAppendFunction.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/json/PostgreSQLJsonArrayAppendFunction.java index 2c158745c0..a37038fe69 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/json/PostgreSQLJsonArrayAppendFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/json/PostgreSQLJsonArrayAppendFunction.java @@ -21,8 +21,11 @@ import org.hibernate.type.spi.TypeConfiguration; */ public class PostgreSQLJsonArrayAppendFunction extends AbstractJsonArrayAppendFunction { - public PostgreSQLJsonArrayAppendFunction(TypeConfiguration typeConfiguration) { + private final boolean supportsLax; + + public PostgreSQLJsonArrayAppendFunction(boolean supportsLax, TypeConfiguration typeConfiguration) { super( typeConfiguration ); + this.supportsLax = supportsLax; } @Override @@ -34,7 +37,14 @@ public class PostgreSQLJsonArrayAppendFunction extends AbstractJsonArrayAppendFu final Expression json = (Expression) arguments.get( 0 ); final Expression jsonPath = (Expression) arguments.get( 1 ); final SqlAstNode value = arguments.get( 2 ); - sqlAppender.appendSql( "(select jsonb_set_lax(t.d,t.p,(t.d)#>t.p||" ); + sqlAppender.appendSql( "(select " ); + if ( supportsLax ) { + sqlAppender.appendSql( "jsonb_set_lax" ); + } + else { + sqlAppender.appendSql( "case when t.d#>t.p is not null then jsonb_set" ); + } + sqlAppender.appendSql( "(t.d,t.p,(t.d)#>t.p||" ); if ( value instanceof Literal && ( (Literal) value ).getLiteralValue() == null ) { sqlAppender.appendSql( "null::jsonb" ); } @@ -47,7 +57,14 @@ public class PostgreSQLJsonArrayAppendFunction extends AbstractJsonArrayAppendFu } sqlAppender.appendSql( ')' ); } - sqlAppender.appendSql( ",false,'return_target') from (values(" ); + sqlAppender.appendSql( ",false" ); + if ( supportsLax ) { + sqlAppender.appendSql( ",'return_target')" ); + } + else { + sqlAppender.appendSql( ") else t.d end" ); + } + sqlAppender.appendSql( " from (values(" ); final boolean needsCast = !isJsonType( json ); if ( needsCast ) { sqlAppender.appendSql( "cast(" ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/json/PostgreSQLJsonRemoveFunction.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/json/PostgreSQLJsonRemoveFunction.java index b8838771e3..9bb175d5e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/json/PostgreSQLJsonRemoveFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/json/PostgreSQLJsonRemoveFunction.java @@ -33,7 +33,6 @@ public class PostgreSQLJsonRemoveFunction extends AbstractJsonRemoveFunction { SqlAstTranslator translator) { final Expression json = (Expression) arguments.get( 0 ); final Expression jsonPath = (Expression) arguments.get( 1 ); - sqlAppender.appendSql( "jsonb_set_lax(" ); final boolean needsCast = !isJsonType( json ) && json instanceof JdbcParameter; if ( needsCast ) { sqlAppender.appendSql( "cast(" ); @@ -42,7 +41,7 @@ public class PostgreSQLJsonRemoveFunction extends AbstractJsonRemoveFunction { if ( needsCast ) { sqlAppender.appendSql( " as jsonb)" ); } - sqlAppender.appendSql( ',' ); + sqlAppender.appendSql( "#-" ); List jsonPathElements = JsonPathHelper.parseJsonPathElements( translator.getLiteralValue( jsonPath ) ); sqlAppender.appendSql( "array" ); @@ -63,7 +62,7 @@ public class PostgreSQLJsonRemoveFunction extends AbstractJsonRemoveFunction { } separator = ','; } - sqlAppender.appendSql( "]::text[],null,true,'delete_key')" ); + sqlAppender.appendSql( "]::text[]" ); } private boolean isJsonType(Expression expression) {