Skip to content

Commit

Permalink
HHH-18587 Implement Oracle array functions using set operations
Browse files Browse the repository at this point in the history
  • Loading branch information
marschall committed Sep 8, 2024
1 parent 8a88ad7 commit c393a6a
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.hibernate.sql.ast.tree.insert.ConflictClause;
import org.hibernate.sql.ast.tree.insert.InsertSelectStatement;
import org.hibernate.sql.ast.tree.insert.Values;
import org.hibernate.sql.ast.tree.predicate.InArrayPredicate;
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.ast.tree.select.QueryGroup;
Expand Down Expand Up @@ -123,6 +124,15 @@ protected boolean needsRecursiveKeywordInWithClause() {
return false;
}

@Override
public void visitInArrayPredicate(InArrayPredicate inArrayPredicate) {
// column in (select column_value from(?) )
inArrayPredicate.getTestExpression().accept( this );
appendSql( " in (select column_value from table(" );
inArrayPredicate.getArrayParameter().accept( this );
appendSql( "))" );
}

@Override
protected boolean supportsWithClauseInSubquery() {
// Oracle has some limitations, see ORA-32034, so we just report false here for simplicity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,34 @@ public void render(
final Expression needleExpression = (Expression) sqlAstArguments.get( 1 );
final JdbcMappingContainer needleTypeContainer = needleExpression.getExpressionType();
final JdbcMapping needleType = needleTypeContainer == null ? null : needleTypeContainer.getSingleJdbcMapping();
final String arrayTypeName = DdlTypeHelper.getTypeName(
haystackExpression.getExpressionType(),
walker.getSessionFactory().getTypeConfiguration()
);
sqlAppender.appendSql( arrayTypeName );
if ( needleType == null || needleType instanceof BasicPluralType<?, ?> ) {
LOG.deprecatedArrayContainsWithArray();
sqlAppender.append( "_includes(" );
haystackExpression.accept( walker );
sqlAppender.append( ',' );
sqlAstArguments.get( 1 ).accept( walker );
sqlAppender.append( ',' );
sqlAppender.append( nullable ? "1" : "0" );
sqlAppender.append( ")>0" );
if ( nullable ) {
final String arrayTypeName = DdlTypeHelper.getTypeName(
haystackExpression.getExpressionType(),
walker.getSessionFactory().getTypeConfiguration()
);
sqlAppender.appendSql( arrayTypeName );
sqlAppender.append( "_includes(" );
haystackExpression.accept( walker );
sqlAppender.append( ',' );
sqlAstArguments.get( 1 ).accept( walker );
sqlAppender.append( ',' );
sqlAppender.append( "1" );
sqlAppender.append( ")>0" );
} else {
sqlAppender.append( " exists (select 1 from (table (" );
needleExpression.accept( walker );
sqlAppender.append( ") join (table (" );
haystackExpression.accept( walker );
sqlAppender.append( ")) using (column_value)))" );
}
}
else {
sqlAppender.append( "_position(" );
haystackExpression.accept( walker );
sqlAppender.append( ',' );
needleExpression.accept( walker );
sqlAppender.append( ")>0" );
sqlAppender.append( " in (select column_value from table(" );
haystackExpression.accept( walker );
sqlAppender.append( "))" );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@

import java.util.List;

import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
import org.hibernate.query.ReturnableType;
import org.hibernate.sql.ast.SqlAstTranslator;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.type.BasicPluralType;
import org.hibernate.type.spi.TypeConfiguration;

public class OracleArrayIncludesFunction extends AbstractArrayIncludesFunction {
Expand All @@ -31,17 +28,27 @@ public void render(
ReturnableType<?> returnType,
SqlAstTranslator<?> walker) {
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
final String arrayTypeName = DdlTypeHelper.getTypeName(
haystackExpression.getExpressionType(),
walker.getSessionFactory().getTypeConfiguration()
);
sqlAppender.appendSql( arrayTypeName );
sqlAppender.append( "_includes(" );
haystackExpression.accept( walker );
sqlAppender.append( ',' );
sqlAstArguments.get( 1 ).accept( walker );
sqlAppender.append( ',' );
sqlAppender.append( nullable ? "1" : "0" );
sqlAppender.append( ")>0" );
if ( nullable ) {
final String arrayTypeName = DdlTypeHelper.getTypeName(
haystackExpression.getExpressionType(),
walker.getSessionFactory().getTypeConfiguration()
);
sqlAppender.appendSql( arrayTypeName );
sqlAppender.append( "_includes(" );
haystackExpression.accept( walker );
sqlAppender.append( ',' );
sqlAstArguments.get( 1 ).accept( walker );
sqlAppender.append( ',' );
sqlAppender.append( "1" );
sqlAppender.append( ")>0" );
}
else {
sqlAppender.append( " not exists ((select column_value from table (" );
sqlAstArguments.get( 1 ).accept( walker );
sqlAppender.append( ")) minus (select column_value from table(" );
haystackExpression.accept( walker );
sqlAppender.append( ")))" );
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,27 @@ public void render(
ReturnableType<?> returnType,
SqlAstTranslator<?> walker) {
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
final String arrayTypeName = DdlTypeHelper.getTypeName(
haystackExpression.getExpressionType(),
walker.getSessionFactory().getTypeConfiguration()
);
sqlAppender.appendSql( arrayTypeName );
sqlAppender.append( "_intersects(" );
haystackExpression.accept( walker );
sqlAppender.append( ',' );
sqlAstArguments.get( 1 ).accept( walker );
sqlAppender.append( ',' );
sqlAppender.append( nullable ? "1" : "0" );
sqlAppender.append( ")>0" );
if ( nullable ) {
final String arrayTypeName = DdlTypeHelper.getTypeName(
haystackExpression.getExpressionType(),
walker.getSessionFactory().getTypeConfiguration()
);
sqlAppender.appendSql( arrayTypeName );
sqlAppender.append( "_intersects(" );
haystackExpression.accept( walker );
sqlAppender.append( ',' );
sqlAstArguments.get( 1 ).accept( walker );
sqlAppender.append( ',' );
sqlAppender.append( "1" );
sqlAppender.append( ")>0" );
}
else {
sqlAppender.append( " exists (select 1 from (table (" );
sqlAstArguments.get( 1 ).accept( walker );
sqlAppender.append( ") join (table (" );
haystackExpression.accept( walker );
sqlAppender.append( ")) using (column_value)))" );
}
}

}

0 comments on commit c393a6a

Please sign in to comment.