Skip to content

Commit e7f5f88

Browse files
marschallbeikov
authored andcommitted
HHH-18587 Implement Oracle array functions using set operations
https://hibernate.atlassian.net/browse/HHH-18587
1 parent 58ee919 commit e7f5f88

File tree

4 files changed

+77
-40
lines changed

4 files changed

+77
-40
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.hibernate.sql.ast.tree.insert.ConflictClause;
4141
import org.hibernate.sql.ast.tree.insert.InsertSelectStatement;
4242
import org.hibernate.sql.ast.tree.insert.Values;
43+
import org.hibernate.sql.ast.tree.predicate.InArrayPredicate;
4344
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
4445
import org.hibernate.sql.ast.tree.predicate.Predicate;
4546
import org.hibernate.sql.ast.tree.select.QueryGroup;
@@ -121,6 +122,15 @@ protected boolean needsRecursiveKeywordInWithClause() {
121122
return false;
122123
}
123124

125+
@Override
126+
public void visitInArrayPredicate(InArrayPredicate inArrayPredicate) {
127+
// column in (select column_value from(?) )
128+
inArrayPredicate.getTestExpression().accept( this );
129+
appendSql( " in (select column_value from table(" );
130+
inArrayPredicate.getArrayParameter().accept( this );
131+
appendSql( "))" );
132+
}
133+
124134
@Override
125135
protected boolean supportsWithClauseInSubquery() {
126136
// Oracle has some limitations, see ORA-32034, so we just report false here for simplicity

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

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,35 @@ public void render(
3232
final Expression needleExpression = (Expression) sqlAstArguments.get( 1 );
3333
final JdbcMappingContainer needleTypeContainer = needleExpression.getExpressionType();
3434
final JdbcMapping needleType = needleTypeContainer == null ? null : needleTypeContainer.getSingleJdbcMapping();
35-
final String arrayTypeName = DdlTypeHelper.getTypeName(
36-
haystackExpression.getExpressionType(),
37-
walker.getSessionFactory().getTypeConfiguration()
38-
);
39-
sqlAppender.appendSql( arrayTypeName );
4035
if ( needleType == null || needleType instanceof BasicPluralType<?, ?> ) {
4136
LOG.deprecatedArrayContainsWithArray();
42-
sqlAppender.append( "_includes(" );
43-
haystackExpression.accept( walker );
44-
sqlAppender.append( ',' );
45-
sqlAstArguments.get( 1 ).accept( walker );
46-
sqlAppender.append( ',' );
47-
sqlAppender.append( nullable ? "1" : "0" );
48-
sqlAppender.append( ")>0" );
37+
if ( nullable ) {
38+
final String arrayTypeName = DdlTypeHelper.getTypeName(
39+
haystackExpression.getExpressionType(),
40+
walker.getSessionFactory().getTypeConfiguration()
41+
);
42+
sqlAppender.appendSql( arrayTypeName );
43+
sqlAppender.append( "_includes(" );
44+
haystackExpression.accept( walker );
45+
sqlAppender.append( ',' );
46+
sqlAstArguments.get( 1 ).accept( walker );
47+
sqlAppender.append( ',' );
48+
sqlAppender.append( "1" );
49+
sqlAppender.append( ")>0" );
50+
}
51+
else {
52+
sqlAppender.append( " exists (select 1 from (table (" );
53+
needleExpression.accept( walker );
54+
sqlAppender.append( ") join (table (" );
55+
haystackExpression.accept( walker );
56+
sqlAppender.append( ")) using (column_value)))" );
57+
}
4958
}
5059
else {
51-
sqlAppender.append( "_position(" );
52-
haystackExpression.accept( walker );
53-
sqlAppender.append( ',' );
5460
needleExpression.accept( walker );
55-
sqlAppender.append( ")>0" );
61+
sqlAppender.append( " in (select column_value from table(" );
62+
haystackExpression.accept( walker );
63+
sqlAppender.append( "))" );
5664
}
5765
}
5866
}

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

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,27 @@ public void render(
2626
ReturnableType<?> returnType,
2727
SqlAstTranslator<?> walker) {
2828
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
29-
final String arrayTypeName = DdlTypeHelper.getTypeName(
30-
haystackExpression.getExpressionType(),
31-
walker.getSessionFactory().getTypeConfiguration()
32-
);
33-
sqlAppender.appendSql( arrayTypeName );
34-
sqlAppender.append( "_includes(" );
35-
haystackExpression.accept( walker );
36-
sqlAppender.append( ',' );
37-
sqlAstArguments.get( 1 ).accept( walker );
38-
sqlAppender.append( ',' );
39-
sqlAppender.append( nullable ? "1" : "0" );
40-
sqlAppender.append( ")>0" );
29+
if ( nullable ) {
30+
final String arrayTypeName = DdlTypeHelper.getTypeName(
31+
haystackExpression.getExpressionType(),
32+
walker.getSessionFactory().getTypeConfiguration()
33+
);
34+
sqlAppender.appendSql( arrayTypeName );
35+
sqlAppender.append( "_includes(" );
36+
haystackExpression.accept( walker );
37+
sqlAppender.append( ',' );
38+
sqlAstArguments.get( 1 ).accept( walker );
39+
sqlAppender.append( ',' );
40+
sqlAppender.append( "1" );
41+
sqlAppender.append( ")>0" );
42+
}
43+
else {
44+
sqlAppender.append( " not exists ((select column_value from table (" );
45+
sqlAstArguments.get( 1 ).accept( walker );
46+
sqlAppender.append( ")) minus (select column_value from table(" );
47+
haystackExpression.accept( walker );
48+
sqlAppender.append( ")))" );
49+
}
50+
4151
}
4252
}

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

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,27 @@ public void render(
2626
ReturnableType<?> returnType,
2727
SqlAstTranslator<?> walker) {
2828
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
29-
final String arrayTypeName = DdlTypeHelper.getTypeName(
30-
haystackExpression.getExpressionType(),
31-
walker.getSessionFactory().getTypeConfiguration()
32-
);
33-
sqlAppender.appendSql( arrayTypeName );
34-
sqlAppender.append( "_intersects(" );
35-
haystackExpression.accept( walker );
36-
sqlAppender.append( ',' );
37-
sqlAstArguments.get( 1 ).accept( walker );
38-
sqlAppender.append( ',' );
39-
sqlAppender.append( nullable ? "1" : "0" );
40-
sqlAppender.append( ")>0" );
29+
if ( nullable ) {
30+
final String arrayTypeName = DdlTypeHelper.getTypeName(
31+
haystackExpression.getExpressionType(),
32+
walker.getSessionFactory().getTypeConfiguration()
33+
);
34+
sqlAppender.appendSql( arrayTypeName );
35+
sqlAppender.append( "_intersects(" );
36+
haystackExpression.accept( walker );
37+
sqlAppender.append( ',' );
38+
sqlAstArguments.get( 1 ).accept( walker );
39+
sqlAppender.append( ',' );
40+
sqlAppender.append( "1" );
41+
sqlAppender.append( ")>0" );
42+
}
43+
else {
44+
sqlAppender.append( " exists (select 1 from (table (" );
45+
sqlAstArguments.get( 1 ).accept( walker );
46+
sqlAppender.append( ") join (table (" );
47+
haystackExpression.accept( walker );
48+
sqlAppender.append( ")) using (column_value)))" );
49+
}
4150
}
4251

4352
}

0 commit comments

Comments
 (0)