Null precedence is now supported if the underlying database supports it.

Original pull request #1156
Closes #821
This commit is contained in:
Chirag Tailor
2022-02-03 10:28:47 -06:00
committed by Jens Schauder
parent 44b7b8fdf3
commit f48bbabc28
13 changed files with 259 additions and 18 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 the original author or authors.
* Copyright 2017-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,6 +51,7 @@ import java.util.stream.Collectors;
* @author Milan Milanov
* @author Myeonghyeon Lee
* @author Mikhail Polivakha
* @author Chirag Tailor
*/
class SqlGenerator {
@@ -714,7 +715,7 @@ class SqlGenerator {
SqlIdentifier columnName = this.entity.getRequiredPersistentProperty(order.getProperty()).getColumnName();
Column column = Column.create(columnName, this.getTable());
return OrderByField.from(column, order.getDirection());
return OrderByField.from(column, order.getDirection()).withNullHandling(order.getNullHandling());
}
/**

View File

@@ -257,6 +257,21 @@ class JdbcAggregateTemplateIntegrationTests {
.containsExactly("Star");
}
@Test // GH-821
@EnabledOnFeature({SUPPORTS_QUOTED_IDS, SUPPORTS_NULL_HANDLING})
void saveAndLoadManyEntitiesWithReferencedEntitySortedWithNullHandling() {
template.save(createLegoSet(null));
template.save(createLegoSet("Star"));
template.save(createLegoSet("Frozen"));
Iterable<LegoSet> reloadedLegoSets = template.findAll(LegoSet.class, Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST)));
assertThat(reloadedLegoSets) //
.extracting("name") //
.containsExactly("Frozen", "Star", null);
}
@Test // DATAJDBC-112
@EnabledOnFeature(SUPPORTS_QUOTED_IDS)
void saveAndLoadManyEntitiesByIdWithReferencedEntity() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 the original author or authors.
* Copyright 2017-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@ import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.ReadOnlyProperty;
import org.springframework.data.annotation.Version;
@@ -64,6 +63,7 @@ import org.springframework.data.relational.core.sql.Table;
* @author Milan Milanov
* @author Myeonghyeon Lee
* @author Mikhail Polivakha
* @author Chirag Tailor
*/
class SqlGeneratorUnitTests {
@@ -245,6 +245,26 @@ class SqlGeneratorUnitTests {
"x_other ASC");
}
@Test // GH-821
void findAllSortedWithNullHandling_resolvesNullHandlingWhenDialectSupportsIt() {
SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class, PostgresDialect.INSTANCE);
String sql = sqlGenerator.getFindAll(Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST)));
assertThat(sql).contains("ORDER BY \"dummy_entity\".\"x_name\" ASC NULLS LAST");
}
@Test // GH-821
void findAllSortedWithNullHandling_ignoresNullHandlingWhenDialectDoesNotSupportIt() {
SqlGenerator sqlGenerator = createSqlGenerator(DummyEntity.class, SqlServerDialect.INSTANCE);
String sql = sqlGenerator.getFindAll(Sort.by(new Sort.Order(Sort.Direction.ASC, "name", Sort.NullHandling.NULLS_LAST)));
assertThat(sql).endsWith("ORDER BY dummy_entity.x_name ASC");
}
@Test // DATAJDBC-101
void findAllPagedByUnpaged() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2021 the original author or authors.
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@ import org.springframework.jdbc.core.JdbcOperations;
* presence or absence of features in tests.
*
* @author Jens Schauder
* @author Chirag Tailor
*/
public class TestDatabaseFeatures {
@@ -83,6 +84,10 @@ public class TestDatabaseFeatures {
assumeThat(database).isNotIn(Database.H2, Database.Hsql);
}
private void supportsNullHandling() {
assumeThat(database).isNotIn(Database.MySql, Database.MariaDb, Database.SqlServer);
}
public void databaseIs(Database database) {
assumeThat(this.database).isEqualTo(database);
}
@@ -115,6 +120,7 @@ public class TestDatabaseFeatures {
SUPPORTS_ARRAYS(TestDatabaseFeatures::supportsArrays), //
SUPPORTS_GENERATED_IDS_IN_REFERENCED_ENTITIES(TestDatabaseFeatures::supportsGeneratedIdsInReferencedEntities), //
SUPPORTS_NANOSECOND_PRECISION(TestDatabaseFeatures::supportsNanosecondPrecision), //
SUPPORTS_NULL_HANDLING(TestDatabaseFeatures::supportsNullHandling),
IS_POSTGRES(f -> f.databaseIs(Database.PostgreSql)), //
IS_HSQL(f -> f.databaseIs(Database.Hsql));