Fix row value comparison emulation rendering issue that occurred on SAP HANA
This commit is contained in:
parent
4ee71faecf
commit
b8afa46d8f
|
@ -34,7 +34,8 @@ stage('Configure') {
|
||||||
buildEnv('8', 'mssql'),
|
buildEnv('8', 'mssql'),
|
||||||
buildEnv('8', 'sybase'),
|
buildEnv('8', 'sybase'),
|
||||||
buildEnv('8', 'hana', 'HANA'),
|
buildEnv('8', 'hana', 'HANA'),
|
||||||
buildEnv('8', 'edb')
|
// Disable EDB for now as the image is not available anymore
|
||||||
|
// buildEnv('8', 'edb')
|
||||||
];
|
];
|
||||||
|
|
||||||
helper.configure {
|
helper.configure {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.SqlTuple;
|
||||||
import org.hibernate.sql.ast.tree.expression.SqlTupleContainer;
|
import org.hibernate.sql.ast.tree.expression.SqlTupleContainer;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
|
||||||
|
@ -36,9 +37,9 @@ public class FieldFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
sqlAppender.appendSql( ", " );
|
sqlAppender.appendSql( ", " );
|
||||||
|
|
||||||
final SqlAstNode argument = sqlAstArguments.get( i );
|
final SqlAstNode argument = sqlAstArguments.get( i );
|
||||||
if ( argument instanceof SqlTupleContainer ) {
|
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( argument );
|
||||||
final List<? extends Expression> expressions = ( (SqlTupleContainer) argument ).getSqlTuple()
|
if ( sqlTuple != null ) {
|
||||||
.getExpressions();
|
final List<? extends Expression> expressions = sqlTuple.getExpressions();
|
||||||
for ( int j = 0; j < expressions.size(); j++ ) {
|
for ( int j = 0; j < expressions.size(); j++ ) {
|
||||||
if ( j != 0 ) {
|
if ( j != 0 ) {
|
||||||
sqlAppender.appendSql( ", " );
|
sqlAppender.appendSql( ", " );
|
||||||
|
|
|
@ -842,20 +842,15 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
columnReferences.get( 0 ).accept( this );
|
columnReferences.get( 0 ).accept( this );
|
||||||
appendSql( " = " );
|
appendSql( " = " );
|
||||||
final Expression assignedValue = assignment.getAssignedValue();
|
final Expression assignedValue = assignment.getAssignedValue();
|
||||||
if ( assignedValue instanceof SqlTupleContainer ) {
|
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( assignedValue );
|
||||||
final SqlTuple sqlTuple = ( (SqlTupleContainer) assignedValue ).getSqlTuple();
|
if ( sqlTuple != null ) {
|
||||||
if ( sqlTuple != null ) {
|
final Expression expression = sqlTuple
|
||||||
final Expression expression = sqlTuple
|
.getExpressions()
|
||||||
.getExpressions()
|
.get( 0 );
|
||||||
.get( 0 );
|
expression.accept( this );
|
||||||
expression.accept( this );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assignedValue.accept( this );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assignment.getAssignedValue().accept( this );
|
assignedValue.accept( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1604,8 +1599,9 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
Function<Expression, Expression> resolveAliasExpression) {
|
Function<Expression, Expression> resolveAliasExpression) {
|
||||||
String separator = "";
|
String separator = "";
|
||||||
for ( Expression partitionExpression : partitionExpressions ) {
|
for ( Expression partitionExpression : partitionExpressions ) {
|
||||||
if ( partitionExpression instanceof SqlTupleContainer ) {
|
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( partitionExpression );
|
||||||
for ( Expression e : ( (SqlTupleContainer) partitionExpression ).getSqlTuple().getExpressions() ) {
|
if ( sqlTuple != null ) {
|
||||||
|
for ( Expression e : sqlTuple.getExpressions() ) {
|
||||||
appendSql( separator );
|
appendSql( separator );
|
||||||
renderPartitionItem( resolveAliasExpression.apply( e ) );
|
renderPartitionItem( resolveAliasExpression.apply( e ) );
|
||||||
separator = COMA_SEPARATOR;
|
separator = COMA_SEPARATOR;
|
||||||
|
@ -1971,10 +1967,10 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
case NOT_DISTINCT_FROM: {
|
case NOT_DISTINCT_FROM: {
|
||||||
appendSql( "exists (select " );
|
appendSql( "exists (select " );
|
||||||
clauseStack.push( Clause.SELECT );
|
clauseStack.push( Clause.SELECT );
|
||||||
renderSelectExpression( lhs );
|
visitSqlSelectExpression( lhs );
|
||||||
appendSql( getFromDualForSelectOnly() );
|
appendSql( getFromDualForSelectOnly() );
|
||||||
appendSql( " intersect select " );
|
appendSql( " intersect select " );
|
||||||
renderSelectExpression( rhs );
|
visitSqlSelectExpression( rhs );
|
||||||
appendSql( getFromDualForSelectOnly() );
|
appendSql( getFromDualForSelectOnly() );
|
||||||
clauseStack.pop();
|
clauseStack.pop();
|
||||||
appendSql( ")" );
|
appendSql( ")" );
|
||||||
|
@ -1996,18 +1992,13 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
final Expression sortExpression = sortSpecification.getSortExpression();
|
final Expression sortExpression = sortSpecification.getSortExpression();
|
||||||
final NullPrecedence nullPrecedence = sortSpecification.getNullPrecedence();
|
final NullPrecedence nullPrecedence = sortSpecification.getNullPrecedence();
|
||||||
final SortOrder sortOrder = sortSpecification.getSortOrder();
|
final SortOrder sortOrder = sortSpecification.getSortOrder();
|
||||||
if ( sortExpression instanceof SqlTupleContainer ) {
|
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( sortExpression );
|
||||||
final SqlTuple sqlTuple = ( (SqlTupleContainer) sortExpression ).getSqlTuple();
|
if ( sqlTuple != null ) {
|
||||||
if ( sqlTuple != null ){
|
String separator = NO_SEPARATOR;
|
||||||
String separator = NO_SEPARATOR;
|
for ( Expression expression : sqlTuple.getExpressions() ) {
|
||||||
for ( Expression expression : sqlTuple.getExpressions() ) {
|
appendSql( separator );
|
||||||
appendSql( separator );
|
visitSortSpecification( expression, sortOrder, nullPrecedence );
|
||||||
visitSortSpecification( expression, sortOrder, nullPrecedence );
|
separator = COMA_SEPARATOR;
|
||||||
separator = COMA_SEPARATOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
visitSortSpecification( sortExpression, sortOrder, nullPrecedence );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3051,10 +3042,14 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitSqlSelection(SqlSelection sqlSelection) {
|
public void visitSqlSelection(SqlSelection sqlSelection) {
|
||||||
final Expression expression = sqlSelection.getExpression();
|
visitSqlSelectExpression( sqlSelection.getExpression() );
|
||||||
if ( expression instanceof SqlTupleContainer ) {
|
}
|
||||||
|
|
||||||
|
protected void visitSqlSelectExpression(Expression expression) {
|
||||||
|
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( expression );
|
||||||
|
if ( sqlTuple != null ) {
|
||||||
boolean isFirst = true;
|
boolean isFirst = true;
|
||||||
for ( Expression e : ( (SqlTupleContainer) expression ).getSqlTuple().getExpressions() ) {
|
for ( Expression e : sqlTuple.getExpressions() ) {
|
||||||
if ( isFirst ) {
|
if ( isFirst ) {
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
}
|
}
|
||||||
|
@ -3556,11 +3551,20 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
protected final void renderCommaSeparatedSelectExpression(Iterable<? extends SqlAstNode> expressions) {
|
protected final void renderCommaSeparatedSelectExpression(Iterable<? extends SqlAstNode> expressions) {
|
||||||
String separator = NO_SEPARATOR;
|
String separator = NO_SEPARATOR;
|
||||||
for ( SqlAstNode expression : expressions ) {
|
for ( SqlAstNode expression : expressions ) {
|
||||||
appendSql( separator );
|
final SqlTuple sqlTuple = SqlTupleContainer.getSqlTuple( expression );
|
||||||
if ( expression instanceof Expression ) {
|
if ( sqlTuple != null ) {
|
||||||
|
for ( Expression e : sqlTuple.getExpressions() ) {
|
||||||
|
appendSql( separator );
|
||||||
|
renderSelectExpression( e );
|
||||||
|
separator = COMA_SEPARATOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( expression instanceof Expression ) {
|
||||||
|
appendSql( separator );
|
||||||
renderSelectExpression( (Expression) expression );
|
renderSelectExpression( (Expression) expression );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
appendSql( separator );
|
||||||
expression.accept( this );
|
expression.accept( this );
|
||||||
}
|
}
|
||||||
separator = COMA_SEPARATOR;
|
separator = COMA_SEPARATOR;
|
||||||
|
@ -4181,7 +4185,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final SqlTuple lhsTuple;
|
final SqlTuple lhsTuple;
|
||||||
if ( ( lhsTuple = getTuple( inListPredicate.getTestExpression() ) ) != null ) {
|
if ( ( lhsTuple = SqlTupleContainer.getSqlTuple( inListPredicate.getTestExpression() ) ) != null ) {
|
||||||
if ( lhsTuple.getExpressions().size() == 1 ) {
|
if ( lhsTuple.getExpressions().size() == 1 ) {
|
||||||
// Special case for tuples with arity 1 as any DBMS supports scalar IN predicates
|
// Special case for tuples with arity 1 as any DBMS supports scalar IN predicates
|
||||||
lhsTuple.getExpressions().get( 0 ).accept( this );
|
lhsTuple.getExpressions().get( 0 ).accept( this );
|
||||||
|
@ -4192,7 +4196,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
String separator = NO_SEPARATOR;
|
String separator = NO_SEPARATOR;
|
||||||
for ( Expression expression : listExpressions ) {
|
for ( Expression expression : listExpressions ) {
|
||||||
appendSql( separator );
|
appendSql( separator );
|
||||||
getTuple( expression ).getExpressions().get( 0 ).accept( this );
|
SqlTupleContainer.getSqlTuple( expression ).getExpressions().get( 0 ).accept( this );
|
||||||
separator = COMA_SEPARATOR;
|
separator = COMA_SEPARATOR;
|
||||||
}
|
}
|
||||||
appendSql( CLOSE_PARENTHESIS );
|
appendSql( CLOSE_PARENTHESIS );
|
||||||
|
@ -4212,7 +4216,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
for ( Expression expression : listExpressions ) {
|
for ( Expression expression : listExpressions ) {
|
||||||
appendSql( separator );
|
appendSql( separator );
|
||||||
renderExpressionsAsSubquery(
|
renderExpressionsAsSubquery(
|
||||||
getTuple( expression ).getExpressions()
|
SqlTupleContainer.getSqlTuple( expression ).getExpressions()
|
||||||
);
|
);
|
||||||
separator = " union all ";
|
separator = " union all ";
|
||||||
}
|
}
|
||||||
|
@ -4224,7 +4228,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
appendSql( separator );
|
appendSql( separator );
|
||||||
emulateTupleComparison(
|
emulateTupleComparison(
|
||||||
lhsTuple.getExpressions(),
|
lhsTuple.getExpressions(),
|
||||||
getTuple( expression ).getExpressions(),
|
SqlTupleContainer.getSqlTuple( expression ).getExpressions(),
|
||||||
comparisonOperator,
|
comparisonOperator,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
@ -4253,18 +4257,10 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final SqlTuple getTuple(Expression expression) {
|
|
||||||
if ( expression instanceof SqlTupleContainer ) {
|
|
||||||
return ( (SqlTupleContainer) expression ).getSqlTuple();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitInSubQueryPredicate(InSubQueryPredicate inSubQueryPredicate) {
|
public void visitInSubQueryPredicate(InSubQueryPredicate inSubQueryPredicate) {
|
||||||
final SqlTuple lhsTuple;
|
final SqlTuple lhsTuple;
|
||||||
if ( ( lhsTuple = getTuple( inSubQueryPredicate.getTestExpression() ) ) != null ) {
|
if ( ( lhsTuple = SqlTupleContainer.getSqlTuple( inSubQueryPredicate.getTestExpression() ) ) != null ) {
|
||||||
if ( lhsTuple.getExpressions().size() == 1 ) {
|
if ( lhsTuple.getExpressions().size() == 1 ) {
|
||||||
// Special case for tuples with arity 1 as any DBMS supports scalar IN predicates
|
// Special case for tuples with arity 1 as any DBMS supports scalar IN predicates
|
||||||
lhsTuple.getExpressions().get( 0 ).accept( this );
|
lhsTuple.getExpressions().get( 0 ).accept( this );
|
||||||
|
@ -4532,7 +4528,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
predicateValue = " is null";
|
predicateValue = " is null";
|
||||||
}
|
}
|
||||||
final SqlTuple tuple;
|
final SqlTuple tuple;
|
||||||
if ( ( tuple = getTuple( expression ) ) != null ) {
|
if ( ( tuple = SqlTupleContainer.getSqlTuple( expression ) ) != null ) {
|
||||||
String separator = NO_SEPARATOR;
|
String separator = NO_SEPARATOR;
|
||||||
for ( Expression exp : tuple.getExpressions() ) {
|
for ( Expression exp : tuple.getExpressions() ) {
|
||||||
appendSql( separator );
|
appendSql( separator );
|
||||||
|
@ -4561,7 +4557,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
|
|
||||||
final SqlTuple lhsTuple;
|
final SqlTuple lhsTuple;
|
||||||
final SqlTuple rhsTuple;
|
final SqlTuple rhsTuple;
|
||||||
if ( ( lhsTuple = getTuple( comparisonPredicate.getLeftHandExpression() ) ) != null ) {
|
if ( ( lhsTuple = SqlTupleContainer.getSqlTuple( comparisonPredicate.getLeftHandExpression() ) ) != null ) {
|
||||||
final Expression rhsExpression = comparisonPredicate.getRightHandExpression();
|
final Expression rhsExpression = comparisonPredicate.getRightHandExpression();
|
||||||
final boolean all;
|
final boolean all;
|
||||||
final QueryPart subquery;
|
final QueryPart subquery;
|
||||||
|
@ -4591,7 +4587,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
renderComparison(
|
renderComparison(
|
||||||
lhsTuple.getExpressions().get( 0 ),
|
lhsTuple.getExpressions().get( 0 ),
|
||||||
operator,
|
operator,
|
||||||
getTuple( comparisonPredicate.getRightHandExpression() ).getExpressions().get( 0 )
|
SqlTupleContainer.getSqlTuple( comparisonPredicate.getRightHandExpression() ).getExpressions().get( 0 )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -4626,7 +4622,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if ( !supportsRowValueConstructorSyntax() ) {
|
else if ( !supportsRowValueConstructorSyntax() ) {
|
||||||
rhsTuple = getTuple( rhsExpression );
|
rhsTuple = SqlTupleContainer.getSqlTuple( rhsExpression );
|
||||||
assert rhsTuple != null;
|
assert rhsTuple != null;
|
||||||
// Some DBs like Oracle support tuples only for the IN subquery predicate
|
// Some DBs like Oracle support tuples only for the IN subquery predicate
|
||||||
if ( ( operator == ComparisonOperator.EQUAL || operator == ComparisonOperator.NOT_EQUAL ) && supportsRowValueConstructorSyntaxInInSubQuery() ) {
|
if ( ( operator == ComparisonOperator.EQUAL || operator == ComparisonOperator.NOT_EQUAL ) && supportsRowValueConstructorSyntaxInInSubQuery() ) {
|
||||||
|
@ -4651,7 +4647,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
renderComparison( comparisonPredicate.getLeftHandExpression(), operator, rhsExpression );
|
renderComparison( comparisonPredicate.getLeftHandExpression(), operator, rhsExpression );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( ( rhsTuple = getTuple( comparisonPredicate.getRightHandExpression() ) ) != null ) {
|
else if ( ( rhsTuple = SqlTupleContainer.getSqlTuple( comparisonPredicate.getRightHandExpression() ) ) != null ) {
|
||||||
final Expression lhsExpression = comparisonPredicate.getLeftHandExpression();
|
final Expression lhsExpression = comparisonPredicate.getLeftHandExpression();
|
||||||
|
|
||||||
if ( lhsExpression instanceof QueryGroup ) {
|
if ( lhsExpression instanceof QueryGroup ) {
|
||||||
|
|
|
@ -6,9 +6,18 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.sql.ast.tree.expression;
|
package org.hibernate.sql.ast.tree.expression;
|
||||||
|
|
||||||
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface SqlTupleContainer {
|
public interface SqlTupleContainer {
|
||||||
SqlTuple getSqlTuple();
|
SqlTuple getSqlTuple();
|
||||||
|
|
||||||
|
static SqlTuple getSqlTuple(SqlAstNode expression) {
|
||||||
|
if ( expression instanceof SqlTupleContainer ) {
|
||||||
|
return ( (SqlTupleContainer) expression ).getSqlTuple();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue