HHH-17934 generate a correct SQL merge statement

(adds the version check if necessary)

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-04-09 20:23:58 +02:00 committed by Christian Beikov
parent 306e59bc74
commit ef0cc752c6
2 changed files with 22 additions and 3 deletions

View File

@ -50,6 +50,11 @@ public abstract class SqlAstTranslatorWithMerge<T extends JdbcOperation> extends
);
}
@Override
public void visitOptionalTableUpdate(OptionalTableUpdate tableUpdate) {
renderMergeStatement(tableUpdate);
}
/**
* Renders the OptionalTableUpdate as a MERGE query.
*
@ -207,8 +212,9 @@ public abstract class SqlAstTranslatorWithMerge<T extends JdbcOperation> extends
protected void renderMergeDelete(OptionalTableUpdate optionalTableUpdate) {
final List<ColumnValueBinding> valueBindings = optionalTableUpdate.getValueBindings();
final List<ColumnValueBinding> optimisticLockBindings = optionalTableUpdate.getOptimisticLockBindings();
appendSql( " when matched " );
renderWhenMatched( optimisticLockBindings );
for ( int i = 0; i < valueBindings.size(); i++ ) {
final ColumnValueBinding binding = valueBindings.get( i );
appendSql( " and " );
@ -220,8 +226,10 @@ public abstract class SqlAstTranslatorWithMerge<T extends JdbcOperation> extends
protected void renderMergeUpdate(OptionalTableUpdate optionalTableUpdate) {
final List<ColumnValueBinding> valueBindings = optionalTableUpdate.getValueBindings();
final List<ColumnValueBinding> optimisticLockBindings = optionalTableUpdate.getOptimisticLockBindings();
appendSql( " when matched then update set " );
renderWhenMatched( optimisticLockBindings );
appendSql( " then update set " );
for ( int i = 0; i < valueBindings.size(); i++ ) {
final ColumnValueBinding binding = valueBindings.get( i );
if ( i > 0 ) {
@ -232,4 +240,15 @@ public abstract class SqlAstTranslatorWithMerge<T extends JdbcOperation> extends
binding.getColumnReference().appendColumnForWrite( this, "s" );
}
}
private void renderWhenMatched(List<ColumnValueBinding> optimisticLockBindings) {
appendSql( " when matched" );
for (int i = 0; i < optimisticLockBindings.size(); i++) {
final ColumnValueBinding binding = optimisticLockBindings.get( i );
appendSql(" and ");
binding.getColumnReference().appendColumnForWrite( this, "t" );
appendSql("<=");
binding.getValueExpression().accept( this );
}
}
}

View File

@ -15,7 +15,7 @@ import static org.junit.Assert.assertEquals;
public class UpsertVersionedTest {
@Test void test(SessionFactoryScope scope) {
scope.inStatelessTransaction(s-> {
s.upsert(new Record(123L,1L,"hello earth"));
s.upsert(new Record(123L,0L,"hello earth"));
s.upsert(new Record(456L,2L,"hello mars"));
});
scope.inStatelessTransaction(s-> {