Vault query - return single column which groups multiple aggregation functions.

* Vault query was returning redundant selects (repeated column used to 'group by') for query with multiple aggregation functions.
This commit is contained in:
szymonsztuka 2017-11-14 11:20:57 +00:00 committed by GitHub
parent 2d997b1fa7
commit 3627cc9fc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 50 deletions

View File

@ -16,6 +16,7 @@ import net.corda.core.utilities.toHexString
import net.corda.core.utilities.trace
import net.corda.node.services.persistence.NodeAttachmentService
import org.hibernate.query.criteria.internal.expression.LiteralExpression
import org.hibernate.query.criteria.internal.path.SingularAttributePath
import org.hibernate.query.criteria.internal.predicate.ComparisonPredicate
import org.hibernate.query.criteria.internal.predicate.InPredicate
import java.time.Instant
@ -287,6 +288,7 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
AggregateFunctionType.MAX -> criteriaBuilder.max(column)
AggregateFunctionType.MIN -> criteriaBuilder.min(column)
}
//TODO investigate possibility to avoid producing redundant joins in SQL for multiple aggregate functions against the same table
aggregateExpressions.add(aggregateExpression)
// optionally order by this aggregate function
expression.orderBy?.let {
@ -302,6 +304,10 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
val groupByExpressions =
columns.map { _column ->
val path = root.get<Any?>(getColumnName(_column))
if (path is SingularAttributePath) //remove the same columns from different joins to match the single column in 'group by' only (from the last join)
aggregateExpressions.removeAll {
elem -> if (elem is SingularAttributePath) elem.attribute.javaMember == path.attribute.javaMember else false
}
aggregateExpressions.add(path)
path
}

View File

@ -395,37 +395,28 @@ public class VaultQueryJavaTests {
Vault.Page<Cash.State> results = vaultService.queryBy(Cash.State.class, criteria);
// DOCEND VaultJavaQueryExample22
assertThat(results.getOtherResults()).hasSize(27);
assertThat(results.getOtherResults()).hasSize(18);
/** CHF */
assertThat(results.getOtherResults().get(0)).isEqualTo(500L);
assertThat(results.getOtherResults().get(1)).isEqualTo("CHF");
assertThat(results.getOtherResults().get(2)).isEqualTo(5L);
assertThat(results.getOtherResults().get(3)).isEqualTo(102L);
assertThat(results.getOtherResults().get(4)).isEqualTo("CHF");
assertThat(results.getOtherResults().get(5)).isEqualTo(94L);
assertThat(results.getOtherResults().get(6)).isEqualTo("CHF");
assertThat(results.getOtherResults().get(7)).isEqualTo(100.00);
assertThat(results.getOtherResults().get(8)).isEqualTo("CHF");
assertThat(results.getOtherResults().get(1)).isEqualTo(5L);
assertThat(results.getOtherResults().get(2)).isEqualTo(102L);
assertThat(results.getOtherResults().get(3)).isEqualTo(94L);
assertThat(results.getOtherResults().get(4)).isEqualTo(100.00);
assertThat(results.getOtherResults().get(5)).isEqualTo("CHF");
/** GBP */
assertThat(results.getOtherResults().get(9)).isEqualTo(400L);
assertThat(results.getOtherResults().get(10)).isEqualTo("GBP");
assertThat(results.getOtherResults().get(11)).isEqualTo(4L);
assertThat(results.getOtherResults().get(12)).isEqualTo(103L);
assertThat(results.getOtherResults().get(13)).isEqualTo("GBP");
assertThat(results.getOtherResults().get(14)).isEqualTo(93L);
assertThat(results.getOtherResults().get(15)).isEqualTo("GBP");
assertThat(results.getOtherResults().get(16)).isEqualTo(100.0);
assertThat(results.getOtherResults().get(17)).isEqualTo("GBP");
assertThat(results.getOtherResults().get(6)).isEqualTo(400L);
assertThat(results.getOtherResults().get(7)).isEqualTo(4L);
assertThat(results.getOtherResults().get(8)).isEqualTo(103L);
assertThat(results.getOtherResults().get(9)).isEqualTo(93L);
assertThat(results.getOtherResults().get(10)).isEqualTo(100.0);
assertThat(results.getOtherResults().get(11)).isEqualTo("GBP");
/** USD */
assertThat(results.getOtherResults().get(18)).isEqualTo(600L);
assertThat(results.getOtherResults().get(19)).isEqualTo("USD");
assertThat(results.getOtherResults().get(20)).isEqualTo(6L);
assertThat(results.getOtherResults().get(21)).isEqualTo(113L);
assertThat(results.getOtherResults().get(22)).isEqualTo("USD");
assertThat(results.getOtherResults().get(23)).isEqualTo(87L);
assertThat(results.getOtherResults().get(24)).isEqualTo("USD");
assertThat(results.getOtherResults().get(25)).isEqualTo(100.0);
assertThat(results.getOtherResults().get(26)).isEqualTo("USD");
assertThat(results.getOtherResults().get(12)).isEqualTo(600L);
assertThat(results.getOtherResults().get(13)).isEqualTo(6L);
assertThat(results.getOtherResults().get(14)).isEqualTo(113L);
assertThat(results.getOtherResults().get(15)).isEqualTo(87L);
assertThat(results.getOtherResults().get(16)).isEqualTo(100.0);
assertThat(results.getOtherResults().get(17)).isEqualTo("USD");
} catch (NoSuchFieldException e) {
e.printStackTrace();

View File

@ -790,34 +790,25 @@ class VaultQueryTests {
.and(avgCriteria))
// DOCEND VaultQueryExample22
assertThat(results.otherResults).hasSize(24)
assertThat(results.otherResults).hasSize(15)
/** CHF */
assertThat(results.otherResults[0]).isEqualTo(50000L)
assertThat(results.otherResults[1]).isEqualTo("CHF")
assertThat(results.otherResults[2]).isEqualTo(10274L)
assertThat(results.otherResults[3]).isEqualTo("CHF")
assertThat(results.otherResults[4]).isEqualTo(9481L)
assertThat(results.otherResults[5]).isEqualTo("CHF")
assertThat(results.otherResults[6]).isEqualTo(10000.0)
assertThat(results.otherResults[7]).isEqualTo("CHF")
assertThat(results.otherResults[1]).isEqualTo(10274L)
assertThat(results.otherResults[2]).isEqualTo(9481L)
assertThat(results.otherResults[3]).isEqualTo(10000.0)
assertThat(results.otherResults[4]).isEqualTo("CHF")
/** GBP */
assertThat(results.otherResults[8]).isEqualTo(40000L)
assertThat(results.otherResults[5]).isEqualTo(40000L)
assertThat(results.otherResults[6]).isEqualTo(10343L)
assertThat(results.otherResults[7]).isEqualTo(9351L)
assertThat(results.otherResults[8]).isEqualTo(10000.0)
assertThat(results.otherResults[9]).isEqualTo("GBP")
assertThat(results.otherResults[10]).isEqualTo(10343L)
assertThat(results.otherResults[11]).isEqualTo("GBP")
assertThat(results.otherResults[12]).isEqualTo(9351L)
assertThat(results.otherResults[13]).isEqualTo("GBP")
assertThat(results.otherResults[14]).isEqualTo(10000.0)
assertThat(results.otherResults[15]).isEqualTo("GBP")
/** USD */
assertThat(results.otherResults[16]).isEqualTo(60000L)
assertThat(results.otherResults[17]).isEqualTo("USD")
assertThat(results.otherResults[18]).isEqualTo(11298L)
assertThat(results.otherResults[19]).isEqualTo("USD")
assertThat(results.otherResults[20]).isEqualTo(8702L)
assertThat(results.otherResults[21]).isEqualTo("USD")
assertThat(results.otherResults[22]).isEqualTo(10000.0)
assertThat(results.otherResults[23]).isEqualTo("USD")
assertThat(results.otherResults[10]).isEqualTo(60000L)
assertThat(results.otherResults[11]).isEqualTo(11298L)
assertThat(results.otherResults[12]).isEqualTo(8702L)
assertThat(results.otherResults[13]).isEqualTo(10000.0)
assertThat(results.otherResults[14]).isEqualTo("USD")
}
}