HHH-18587 Implement Oracle array functions using set operations
https://hibernate.atlassian.net/browse/HHH-18587
This commit is contained in:
parent
8a88ad7f59
commit
91627440a3
|
@ -42,6 +42,7 @@ import org.hibernate.sql.ast.tree.from.ValuesTableReference;
|
|||
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;
|
||||
|
@ -123,6 +124,15 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends SqlAstTrans
|
|||
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
|
||||
|
|
|
@ -34,27 +34,35 @@ public class OracleArrayContainsFunction extends AbstractArrayContainsFunction {
|
|||
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( "))" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,11 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
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 {
|
||||
|
@ -31,17 +28,27 @@ public class OracleArrayIncludesFunction extends AbstractArrayIncludesFunction {
|
|||
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( ")))" );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,18 +28,27 @@ public class OracleArrayIntersectsFunction extends AbstractArrayIntersectsFuncti
|
|||
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)))" );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue