Skip to content

Commit c700dcd

Browse files
committed
HHH-17355 Smoothen some rough edges with parameter typing and PG12 support
1 parent d7bdb5c commit c700dcd

File tree

41 files changed

+374
-101
lines changed

Some content is hidden

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

41 files changed

+374
-101
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,8 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
477477
functionFactory.arrayRemoveIndex_unnest( true );
478478
functionFactory.arraySlice_operator();
479479
functionFactory.arrayReplace();
480-
functionFactory.arrayTrim_trim_array();
481-
functionFactory.arrayFill_postgresql();
480+
functionFactory.arrayTrim_unnest();
481+
functionFactory.arrayFill_cockroachdb();
482482
functionFactory.arrayToString_postgresql();
483483

484484
functionContributions.getFunctionRegistry().register(

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
597597
functionFactory.arrayRemoveIndex_unnest( true );
598598
functionFactory.arraySlice_operator();
599599
functionFactory.arrayReplace();
600-
functionFactory.arrayTrim_trim_array();
600+
if ( getVersion().isSameOrAfter( 14 ) ) {
601+
functionFactory.arrayTrim_trim_array();
602+
}
603+
else {
604+
functionFactory.arrayTrim_unnest();
605+
}
601606
functionFactory.arrayFill_postgresql();
602607
functionFactory.arrayToString_postgresql();
603608

hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,8 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
464464
functionFactory.arrayRemoveIndex_unnest( true );
465465
functionFactory.arraySlice_operator();
466466
functionFactory.arrayReplace();
467-
functionFactory.arrayTrim_trim_array();
468-
functionFactory.arrayFill_postgresql();
467+
functionFactory.arrayTrim_unnest();
468+
functionFactory.arrayFill_cockroachdb();
469469
functionFactory.arrayToString_postgresql();
470470

471471
functionContributions.getFunctionRegistry().register(

hibernate-core/src/main/java/org/hibernate/dialect/MySQLSqlAstTranslator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public static String getSqlType(CastTarget castTarget, Dialect dialect) {
4646
}
4747

4848
public static String getSqlType(CastTarget castTarget, SessionFactoryImplementor factory) {
49-
final String sqlType = getCastTypeName( castTarget, factory );
49+
final String sqlType = getCastTypeName( castTarget, factory.getTypeConfiguration() );
5050
return getSqlType( castTarget, sqlType, factory.getJdbcServices().getDialect() );
5151
}
5252

hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
645645
functionFactory.arrayRemoveIndex_unnest( true );
646646
functionFactory.arraySlice_operator();
647647
functionFactory.arrayReplace();
648-
functionFactory.arrayTrim_trim_array();
648+
if ( getVersion().isSameOrAfter( 14 ) ) {
649+
functionFactory.arrayTrim_trim_array();
650+
}
651+
else {
652+
functionFactory.arrayTrim_unnest();
653+
}
649654
functionFactory.arrayFill_postgresql();
650655
functionFactory.arrayToString_postgresql();
651656

hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.hibernate.dialect.function.array.ArraySliceUnnestFunction;
3131
import org.hibernate.dialect.function.array.ArrayToStringFunction;
3232
import org.hibernate.dialect.function.array.ArrayViaArgumentReturnTypeResolver;
33+
import org.hibernate.dialect.function.array.CockroachArrayFillFunction;
3334
import org.hibernate.dialect.function.array.ElementViaArrayArgumentReturnTypeResolver;
3435
import org.hibernate.dialect.function.array.H2ArrayContainsFunction;
3536
import org.hibernate.dialect.function.array.H2ArrayFillFunction;
@@ -72,6 +73,7 @@
7273
import org.hibernate.dialect.function.array.OracleArrayConstructorFunction;
7374
import org.hibernate.dialect.function.array.OracleArrayContainsFunction;
7475
import org.hibernate.dialect.function.array.PostgreSQLArrayPositionsFunction;
76+
import org.hibernate.dialect.function.array.PostgreSQLArrayTrimEmulation;
7577
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
7678
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
7779
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
@@ -3166,6 +3168,13 @@ public void arrayTrim_trim_array() {
31663168
.register();
31673169
}
31683170

3171+
/**
3172+
* PostgreSQL array_trim() emulation for versions before 14
3173+
*/
3174+
public void arrayTrim_unnest() {
3175+
functionRegistry.register( "array_trim", new PostgreSQLArrayTrimEmulation() );
3176+
}
3177+
31693178
/**
31703179
* Oracle array_trim() function
31713180
*/
@@ -3197,6 +3206,14 @@ public void arrayFill_postgresql() {
31973206
functionRegistry.register( "array_fill_list", new PostgreSQLArrayFillFunction( true ) );
31983207
}
31993208

3209+
/**
3210+
* Cockroach array_fill() function
3211+
*/
3212+
public void arrayFill_cockroachdb() {
3213+
functionRegistry.register( "array_fill", new CockroachArrayFillFunction( false ) );
3214+
functionRegistry.register( "array_fill_list", new CockroachArrayFillFunction( true ) );
3215+
}
3216+
32003217
/**
32013218
* Oracle array_fill() function
32023219
*/
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
6+
*/
7+
package org.hibernate.dialect.function.array;
8+
9+
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
10+
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
11+
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
12+
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
13+
14+
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.ANY;
15+
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
16+
17+
/**
18+
* Encapsulates the validator, return type and argument type resolvers for the array_remove functions.
19+
* Subclasses only have to implement the rendering.
20+
*/
21+
public abstract class AbstractArrayTrimFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
22+
23+
public AbstractArrayTrimFunction() {
24+
super(
25+
"array_trim",
26+
StandardArgumentsValidators.composite(
27+
new ArgumentTypesValidator( null, ANY, INTEGER ),
28+
ArrayArgumentValidator.DEFAULT_INSTANCE
29+
),
30+
ArrayViaArgumentReturnTypeResolver.DEFAULT_INSTANCE,
31+
StandardFunctionArgumentTypeResolvers.composite(
32+
StandardFunctionArgumentTypeResolvers.invariant( ANY, INTEGER ),
33+
StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE
34+
)
35+
);
36+
}
37+
}

hibernate-core/src/main/java/org/hibernate/dialect/function/array/ArrayContainsOperatorFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void render(
6565
sqlAppender.append( "] as " );
6666
sqlAppender.append( DdlTypeHelper.getCastTypeName(
6767
haystackExpression.getExpressionType(),
68-
walker
68+
walker.getSessionFactory().getTypeConfiguration()
6969
) );
7070
sqlAppender.append( ')' );
7171
}

hibernate-core/src/main/java/org/hibernate/dialect/function/array/ArrayRemoveIndexUnnestFunction.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ public void render(
6161
sqlAppender.append( "),");
6262
if ( castEmptyArrayLiteral ) {
6363
sqlAppender.append( "cast(array[] as " );
64-
sqlAppender.append( DdlTypeHelper.getCastTypeName( returnType, walker ) );
64+
sqlAppender.append( DdlTypeHelper.getCastTypeName(
65+
returnType,
66+
walker.getSessionFactory().getTypeConfiguration()
67+
) );
6568
sqlAppender.append( ')' );
6669
}
6770
else {

hibernate-core/src/main/java/org/hibernate/dialect/function/array/ArraySliceUnnestFunction.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ public void render(
6868
sqlAppender.append( "),");
6969
if ( castEmptyArrayLiteral ) {
7070
sqlAppender.append( "cast(array[] as " );
71-
sqlAppender.append( DdlTypeHelper.getCastTypeName( returnType, walker ) );
71+
sqlAppender.append( DdlTypeHelper.getCastTypeName(
72+
returnType,
73+
walker.getSessionFactory().getTypeConfiguration()
74+
) );
7275
sqlAppender.append( ')' );
7376
}
7477
else {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
5+
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
6+
*/
7+
package org.hibernate.dialect.function.array;
8+
9+
import java.util.List;
10+
11+
import org.hibernate.query.ReturnableType;
12+
import org.hibernate.sql.ast.SqlAstTranslator;
13+
import org.hibernate.sql.ast.spi.SqlAppender;
14+
import org.hibernate.sql.ast.tree.SqlAstNode;
15+
import org.hibernate.sql.ast.tree.expression.Expression;
16+
import org.hibernate.sql.ast.tree.expression.Literal;
17+
18+
/**
19+
* Implement the array fill function by using {@code generate_series}.
20+
*/
21+
public class CockroachArrayFillFunction extends AbstractArrayFillFunction {
22+
23+
public CockroachArrayFillFunction(boolean list) {
24+
super( list );
25+
}
26+
27+
@Override
28+
public void render(
29+
SqlAppender sqlAppender,
30+
List<? extends SqlAstNode> sqlAstArguments,
31+
ReturnableType<?> returnType,
32+
SqlAstTranslator<?> walker) {
33+
sqlAppender.append( "coalesce(case when " );
34+
sqlAstArguments.get( 1 ).accept( walker );
35+
sqlAppender.append( "<>0 then (select array_agg(" );
36+
final String elementCastType;
37+
final Expression elementExpression = (Expression) sqlAstArguments.get( 0 );
38+
if ( needsElementCasting( elementExpression ) ) {
39+
elementCastType = DdlTypeHelper.getCastTypeName(
40+
elementExpression.getExpressionType(),
41+
walker.getSessionFactory().getTypeConfiguration()
42+
);
43+
sqlAppender.append( "cast(" );
44+
}
45+
else {
46+
elementCastType = null;
47+
}
48+
sqlAstArguments.get( 0 ).accept( walker );
49+
if ( elementCastType != null ) {
50+
sqlAppender.append( " as " );
51+
sqlAppender.append( elementCastType );
52+
sqlAppender.append( ')' );
53+
}
54+
sqlAppender.append( ") from generate_series(1," );
55+
sqlAstArguments.get( 1 ).accept( walker );
56+
sqlAppender.append( ",1))) end,array[])" );
57+
}
58+
59+
private static boolean needsElementCasting(Expression elementExpression) {
60+
// PostgreSQL needs casting of null and string literal expressions
61+
return elementExpression instanceof Literal && (
62+
elementExpression.getExpressionType().getSingleJdbcMapping().getJdbcType().isString()
63+
|| ( (Literal) elementExpression ).getLiteralValue() == null
64+
);
65+
}
66+
}

hibernate-core/src/main/java/org/hibernate/dialect/function/array/DdlTypeHelper.java

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.hibernate.metamodel.mapping.SqlTypedMapping;
1717
import org.hibernate.metamodel.model.domain.DomainType;
1818
import org.hibernate.query.ReturnableType;
19-
import org.hibernate.sql.ast.SqlAstTranslator;
2019
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
2120
import org.hibernate.type.BasicType;
2221
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
@@ -60,71 +59,91 @@ public static BasicType<?> resolveListType(DomainType<?> elementType, TypeConfig
6059
);
6160
}
6261

63-
public static String getTypeName(BasicType<?> type, SqlAstTranslator<?> walker) {
64-
return getTypeName( (JdbcMappingContainer) type, walker );
62+
public static String getTypeName(BasicType<?> type, TypeConfiguration typeConfiguration) {
63+
return getTypeName( (JdbcMappingContainer) type, typeConfiguration );
6564
}
6665

67-
public static String getTypeName(JdbcMappingContainer type, SqlAstTranslator<?> walker) {
66+
public static String getTypeName(BasicType<?> type, Size size, TypeConfiguration typeConfiguration) {
67+
return getTypeName( (JdbcMappingContainer) type, size, typeConfiguration );
68+
}
69+
70+
public static String getTypeName(JdbcMappingContainer type, TypeConfiguration typeConfiguration) {
71+
return getTypeName( type, Size.nil(), typeConfiguration );
72+
}
73+
74+
public static String getTypeName(JdbcMappingContainer type, Size size, TypeConfiguration typeConfiguration) {
6875
if ( type instanceof SqlTypedMapping ) {
69-
return AbstractSqlAstTranslator.getSqlTypeName( (SqlTypedMapping) type, walker.getSessionFactory() );
76+
return AbstractSqlAstTranslator.getSqlTypeName( (SqlTypedMapping) type, typeConfiguration );
7077
}
7178
else {
7279
final BasicType<?> basicType = (BasicType<?>) type.getSingleJdbcMapping();
73-
final TypeConfiguration typeConfiguration = walker.getSessionFactory().getTypeConfiguration();
7480
final DdlTypeRegistry ddlTypeRegistry = typeConfiguration.getDdlTypeRegistry();
7581
final DdlType ddlType = ddlTypeRegistry.getDescriptor(
7682
basicType.getJdbcType().getDdlTypeCode()
7783
);
78-
return ddlType.getTypeName( Size.nil(), basicType, ddlTypeRegistry );
84+
return ddlType.getTypeName( size, basicType, ddlTypeRegistry );
7985
}
8086
}
8187

82-
public static String getTypeName(ReturnableType<?> type, SqlAstTranslator<?> walker) {
88+
public static String getTypeName(ReturnableType<?> type, TypeConfiguration typeConfiguration) {
89+
return getTypeName( type, Size.nil(), typeConfiguration );
90+
}
91+
92+
public static String getTypeName(ReturnableType<?> type, Size size, TypeConfiguration typeConfiguration) {
8393
if ( type instanceof SqlTypedMapping ) {
84-
return AbstractSqlAstTranslator.getSqlTypeName( (SqlTypedMapping) type, walker.getSessionFactory() );
94+
return AbstractSqlAstTranslator.getSqlTypeName( (SqlTypedMapping) type, typeConfiguration );
8595
}
8696
else {
8797
final BasicType<?> basicType = (BasicType<?>) ( (JdbcMappingContainer) type ).getSingleJdbcMapping();
88-
final TypeConfiguration typeConfiguration = walker.getSessionFactory().getTypeConfiguration();
8998
final DdlTypeRegistry ddlTypeRegistry = typeConfiguration.getDdlTypeRegistry();
9099
final DdlType ddlType = ddlTypeRegistry.getDescriptor(
91100
basicType.getJdbcType().getDdlTypeCode()
92101
);
93-
return ddlType.getTypeName( Size.nil(), basicType, ddlTypeRegistry );
102+
return ddlType.getTypeName( size, basicType, ddlTypeRegistry );
94103
}
95104
}
96105

97-
public static String getCastTypeName(BasicType<?> type, SqlAstTranslator<?> walker) {
98-
return getCastTypeName( (JdbcMappingContainer) type, walker );
106+
public static String getCastTypeName(BasicType<?> type, TypeConfiguration typeConfiguration) {
107+
return getCastTypeName( (JdbcMappingContainer) type, typeConfiguration );
99108
}
100109

101-
public static String getCastTypeName(JdbcMappingContainer type, SqlAstTranslator<?> walker) {
110+
public static String getCastTypeName(BasicType<?> type, Size size, TypeConfiguration typeConfiguration) {
111+
return getCastTypeName( (JdbcMappingContainer) type, size, typeConfiguration );
112+
}
113+
114+
public static String getCastTypeName(JdbcMappingContainer type, TypeConfiguration typeConfiguration) {
115+
return getCastTypeName( type, Size.nil(), typeConfiguration );
116+
}
117+
118+
public static String getCastTypeName(JdbcMappingContainer type, Size size, TypeConfiguration typeConfiguration) {
102119
if ( type instanceof SqlTypedMapping ) {
103-
return AbstractSqlAstTranslator.getCastTypeName( (SqlTypedMapping) type, walker.getSessionFactory() );
120+
return AbstractSqlAstTranslator.getCastTypeName( (SqlTypedMapping) type, typeConfiguration );
104121
}
105122
else {
106123
final BasicType<?> basicType = (BasicType<?>) type.getSingleJdbcMapping();
107-
final TypeConfiguration typeConfiguration = walker.getSessionFactory().getTypeConfiguration();
108124
final DdlTypeRegistry ddlTypeRegistry = typeConfiguration.getDdlTypeRegistry();
109125
final DdlType ddlType = ddlTypeRegistry.getDescriptor(
110126
basicType.getJdbcType().getDdlTypeCode()
111127
);
112-
return ddlType.getCastTypeName( Size.nil(), basicType, ddlTypeRegistry );
128+
return ddlType.getCastTypeName( size, basicType, ddlTypeRegistry );
113129
}
114130
}
115131

116-
public static String getCastTypeName(ReturnableType<?> type, SqlAstTranslator<?> walker) {
132+
public static String getCastTypeName(ReturnableType<?> type, TypeConfiguration typeConfiguration) {
133+
return getCastTypeName( type, Size.nil(), typeConfiguration );
134+
}
135+
136+
public static String getCastTypeName(ReturnableType<?> type, Size size, TypeConfiguration typeConfiguration) {
117137
if ( type instanceof SqlTypedMapping ) {
118-
return AbstractSqlAstTranslator.getCastTypeName( (SqlTypedMapping) type, walker.getSessionFactory() );
138+
return AbstractSqlAstTranslator.getCastTypeName( (SqlTypedMapping) type, typeConfiguration );
119139
}
120140
else {
121141
final BasicType<?> basicType = (BasicType<?>) ( (JdbcMappingContainer) type ).getSingleJdbcMapping();
122-
final TypeConfiguration typeConfiguration = walker.getSessionFactory().getTypeConfiguration();
123142
final DdlTypeRegistry ddlTypeRegistry = typeConfiguration.getDdlTypeRegistry();
124143
final DdlType ddlType = ddlTypeRegistry.getDescriptor(
125144
basicType.getJdbcType().getDdlTypeCode()
126145
);
127-
return ddlType.getCastTypeName( Size.nil(), basicType, ddlTypeRegistry );
146+
return ddlType.getCastTypeName( size, basicType, ddlTypeRegistry );
128147
}
129148
}
130149

hibernate-core/src/main/java/org/hibernate/dialect/function/array/HSQLArrayConstructorFunction.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ public void render(
2929
SqlAstTranslator<?> walker) {
3030
final String castTypeName;
3131
if ( returnType != null && hasOnlyBottomArguments( arguments ) ) {
32-
castTypeName = DdlTypeHelper.getCastTypeName( returnType, walker );
32+
castTypeName = DdlTypeHelper.getCastTypeName(
33+
returnType,
34+
walker.getSessionFactory().getTypeConfiguration()
35+
);
3336
sqlAppender.append( "cast(" );
3437
}
3538
else {

hibernate-core/src/main/java/org/hibernate/dialect/function/array/OracleArrayConcatElementFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public void render(
3434
final String arrayTypeName = DdlTypeHelper.getTypeName(
3535
prepend ? secondArgument.getExpressionType()
3636
: firstArgument.getExpressionType(),
37-
walker
37+
walker.getSessionFactory().getTypeConfiguration()
3838
);
3939
sqlAppender.append( arrayTypeName );
4040
sqlAppender.append( "_concat(" );

hibernate-core/src/main/java/org/hibernate/dialect/function/array/OracleArrayConcatFunction.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ public void render(
2929
List<? extends SqlAstNode> sqlAstArguments,
3030
ReturnableType<?> returnType,
3131
SqlAstTranslator<?> walker) {
32-
final String arrayTypeName = DdlTypeHelper.getTypeName( (JdbcMappingContainer) returnType, walker );
32+
final String arrayTypeName = DdlTypeHelper.getTypeName(
33+
(JdbcMappingContainer) returnType,
34+
walker.getSessionFactory().getTypeConfiguration()
35+
);
3336
sqlAppender.append( arrayTypeName );
3437
sqlAppender.append( "_concat" );
3538
super.render( sqlAppender, sqlAstArguments, returnType, walker );

0 commit comments

Comments
 (0)