removing a questionable grammar rule seems to make implicit collection joins work
This commit is contained in:
parent
9ebac67737
commit
437da23961
|
@ -425,10 +425,10 @@ collectionValueNavigablePath
|
|||
;
|
||||
|
||||
/**
|
||||
* A 'key()' function that "breaks" a path expression
|
||||
* A 'key()' or 'index()' function that "breaks" a path expression
|
||||
*/
|
||||
mapKeyNavigablePath
|
||||
: KEY LEFT_PAREN path RIGHT_PAREN pathContinuation?
|
||||
: (KEY|INDEX) LEFT_PAREN path RIGHT_PAREN pathContinuation?
|
||||
;
|
||||
|
||||
|
||||
|
@ -947,7 +947,7 @@ parameter
|
|||
function
|
||||
: standardFunction
|
||||
| aggregateFunction
|
||||
| jpaCollectionFunction
|
||||
| collectionSizeFunction
|
||||
| indexAggregateFunction
|
||||
| elementAggregateFunction
|
||||
| collectionFunctionMisuse
|
||||
|
@ -995,11 +995,10 @@ genericFunctionArguments
|
|||
;
|
||||
|
||||
/**
|
||||
* The special 'size()' and 'index()' functions defined by JPQL
|
||||
* The special 'size()' function defined by JPQL
|
||||
*/
|
||||
jpaCollectionFunction
|
||||
: SIZE LEFT_PAREN path RIGHT_PAREN # CollectionSizeFunction
|
||||
| INDEX LEFT_PAREN identifier RIGHT_PAREN # CollectionIndexFunction
|
||||
collectionSizeFunction
|
||||
: SIZE LEFT_PAREN path RIGHT_PAREN
|
||||
;
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.query.hql.internal;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.hql.HqlInterpretationException;
|
||||
import org.hibernate.query.hql.spi.DotIdentifierConsumer;
|
||||
import org.hibernate.query.hql.spi.SemanticPathPart;
|
||||
import org.hibernate.query.hql.spi.SqmPathRegistry;
|
||||
|
|
|
@ -104,6 +104,7 @@ import org.hibernate.query.sqm.tree.domain.AbstractSqmFrom;
|
|||
import org.hibernate.query.sqm.tree.domain.SqmCorrelation;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmElementAggregateFunction;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmIndexAggregateFunction;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmListJoin;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmMapEntryReference;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmMapJoin;
|
||||
import org.hibernate.query.sqm.tree.domain.SqmPath;
|
||||
|
@ -4210,24 +4211,6 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPath<?> visitCollectionIndexFunction(HqlParser.CollectionIndexFunctionContext ctx) {
|
||||
final String alias = ctx.getChild( 2 ).getText();
|
||||
final SqmFrom<?, ?> sqmFrom = processingStateStack.getCurrent().getPathRegistry().findFromByAlias( alias );
|
||||
|
||||
if ( sqmFrom == null ) {
|
||||
throw new ParsingException( "Alias '" + alias + "' did not resolve to a declared identification variable" );
|
||||
}
|
||||
|
||||
final SqmPathSource<?> pluralAttribute = sqmFrom.getReferencedPathSource();
|
||||
|
||||
if ( !( pluralAttribute instanceof PluralPersistentAttribute<?, ?, ?> ) ) {
|
||||
throw new ParsingException( "Alias '" + alias + "' did not resolve to a many-valued attribute" );
|
||||
}
|
||||
|
||||
return sqmFrom.resolvePathPart( CollectionPart.Nature.INDEX.getName(), true, this );
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
private boolean isIndexedPluralAttribute(SqmPath<?> path) {
|
||||
return path.getReferencedPathSource() instanceof PluralPersistentAttribute;
|
||||
|
@ -4529,41 +4512,6 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
|
||||
@Override
|
||||
public SqmPath<?> visitCollectionValueNavigablePath(HqlParser.CollectionValueNavigablePathContext ctx) {
|
||||
final SqmPath<?> pluralAttributePath = consumeDomainPath( (HqlParser.PathContext) ctx.getChild( 2 ) );
|
||||
final SqmPathSource<?> referencedPathSource = pluralAttributePath.getReferencedPathSource();
|
||||
final TerminalNode firstNode = (TerminalNode) ctx.getChild( 0 );
|
||||
|
||||
if ( !(referencedPathSource instanceof PluralPersistentAttribute<?, ?, ?> ) ) {
|
||||
throw new PathException(
|
||||
String.format(
|
||||
"Argument of '%s' is not a plural path '%s'",
|
||||
firstNode.getSymbol().getText(),
|
||||
pluralAttributePath.getNavigablePath()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
final PluralPersistentAttribute<?, ?, ?> attribute = (PluralPersistentAttribute<?, ?, ?>) referencedPathSource;
|
||||
|
||||
if ( getCreationOptions().useStrictJpaCompliance() ) {
|
||||
if ( attribute.getCollectionClassification() != CollectionClassification.MAP ) {
|
||||
throw new StrictJpaComplianceViolation( StrictJpaComplianceViolation.Type.VALUE_FUNCTION_ON_NON_MAP );
|
||||
}
|
||||
}
|
||||
|
||||
SqmPath<?> result = pluralAttributePath.resolvePathPart( CollectionPart.Nature.ELEMENT.getName(), true, this );
|
||||
|
||||
if ( ctx.getChildCount() == 5 ) {
|
||||
result = consumeDomainPath( (HqlParser.SimplePathContext) ctx.getChild( 4 ).getChild( 1 ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public SqmPath visitMapKeyNavigablePath(HqlParser.MapKeyNavigablePathContext ctx) {
|
||||
final DotIdentifierConsumer consumer = dotIdentifierConsumerStack.getCurrent();
|
||||
final boolean madeNested;
|
||||
if ( consumer instanceof QualifiedJoinPathConsumer) {
|
||||
|
@ -4579,6 +4527,91 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
final SqmPath<?> sqmPath = consumeDomainPath( (HqlParser.PathContext) ctx.getChild( 2 ) );
|
||||
final boolean hasContinuation = ctx.getChildCount() == 5;
|
||||
|
||||
final SqmPathSource<?> referencedPathSource = sqmPath.getReferencedPathSource();
|
||||
final TerminalNode firstNode = (TerminalNode) ctx.getChild( 0 );
|
||||
checkPluralPath( sqmPath, referencedPathSource, firstNode );
|
||||
|
||||
if ( getCreationOptions().useStrictJpaCompliance() ) {
|
||||
final PluralPersistentAttribute<?, ?, ?> attribute = (PluralPersistentAttribute<?, ?, ?>) referencedPathSource;
|
||||
if ( attribute.getCollectionClassification() != CollectionClassification.MAP
|
||||
&& firstNode.getSymbol().getType() == HqlParser.VALUE ) {
|
||||
throw new StrictJpaComplianceViolation( StrictJpaComplianceViolation.Type.VALUE_FUNCTION_ON_NON_MAP );
|
||||
}
|
||||
}
|
||||
|
||||
SqmPath<?> result;
|
||||
if ( consumer instanceof QualifiedJoinPathConsumer) {
|
||||
if ( madeNested && !hasContinuation ) {
|
||||
// Reset the nested state before consuming the terminal identifier
|
||||
( (QualifiedJoinPathConsumer) consumer ).setNested( false );
|
||||
}
|
||||
consumer.consumeIdentifier( CollectionPart.Nature.ELEMENT.getName(), false, !hasContinuation );
|
||||
result = (SqmPath<?>) consumer.getConsumedPart();
|
||||
}
|
||||
else {
|
||||
result = sqmPath.resolvePathPart( CollectionPart.Nature.ELEMENT.getName(), true, this );
|
||||
}
|
||||
|
||||
if ( hasContinuation ) {
|
||||
if ( madeNested ) {
|
||||
// Reset the nested state before consuming the terminal identifier
|
||||
( (QualifiedJoinPathConsumer) consumer ).setNested( false );
|
||||
}
|
||||
final HqlParser.SimplePathContext identCtx = (HqlParser.SimplePathContext) ctx.getChild( 4 )
|
||||
.getChild( 1 );
|
||||
if ( consumer instanceof QualifiedJoinPathConsumer) {
|
||||
result = consumeDomainPath( identCtx );
|
||||
}
|
||||
else {
|
||||
dotIdentifierConsumerStack.push(
|
||||
new BasicDotIdentifierConsumer( result, this ) {
|
||||
@Override
|
||||
protected void reset() {
|
||||
}
|
||||
}
|
||||
);
|
||||
try {
|
||||
result = consumeDomainPath( identCtx );
|
||||
}
|
||||
finally {
|
||||
dotIdentifierConsumerStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SqmPath<?> visitMapKeyNavigablePath(HqlParser.MapKeyNavigablePathContext ctx) {
|
||||
final DotIdentifierConsumer consumer = dotIdentifierConsumerStack.getCurrent();
|
||||
final boolean madeNested;
|
||||
if ( consumer instanceof QualifiedJoinPathConsumer) {
|
||||
final QualifiedJoinPathConsumer qualifiedJoinPathConsumer = (QualifiedJoinPathConsumer) consumer;
|
||||
madeNested = !qualifiedJoinPathConsumer.isNested();
|
||||
if ( madeNested ) {
|
||||
qualifiedJoinPathConsumer.setNested( true );
|
||||
}
|
||||
}
|
||||
else {
|
||||
madeNested = false;
|
||||
}
|
||||
final SqmPath<?> sqmPath = consumeDomainPath( (HqlParser.PathContext) ctx.getChild( 2 ) );
|
||||
final boolean hasContinuation = ctx.getChildCount() == 5;
|
||||
|
||||
final SqmPathSource<?> referencedPathSource = sqmPath.getReferencedPathSource();
|
||||
final TerminalNode firstNode = (TerminalNode) ctx.getChild( 0 );
|
||||
checkPluralPath( sqmPath, referencedPathSource, firstNode );
|
||||
|
||||
if ( getCreationOptions().useStrictJpaCompliance() ) {
|
||||
final PluralPersistentAttribute<?, ?, ?> attribute = (PluralPersistentAttribute<?, ?, ?>) referencedPathSource;
|
||||
if ( attribute.getCollectionClassification() != CollectionClassification.MAP
|
||||
&& firstNode.getSymbol().getType() == HqlParser.KEY ) {
|
||||
throw new StrictJpaComplianceViolation( StrictJpaComplianceViolation.Type.KEY_FUNCTION_ON_NON_MAP );
|
||||
}
|
||||
}
|
||||
|
||||
SqmPath<?> result;
|
||||
if ( sqmPath instanceof SqmMapJoin ) {
|
||||
final SqmMapJoin<?, ?, ?> sqmMapJoin = (SqmMapJoin<?, ?, ?>) sqmPath;
|
||||
|
@ -4594,6 +4627,13 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
result = sqmMapJoin.key();
|
||||
}
|
||||
}
|
||||
else if ( sqmPath instanceof SqmListJoin ) {
|
||||
if ( hasContinuation ) {
|
||||
throw new SemanticException("list index may not be dereferenced");
|
||||
}
|
||||
SqmListJoin<?,?> listJoin = (SqmListJoin<?,?>) sqmPath;
|
||||
result = listJoin.resolvePathPart( CollectionPart.Nature.INDEX.getName(), true, this );
|
||||
}
|
||||
else {
|
||||
assert sqmPath instanceof SqmPluralValuedSimplePath;
|
||||
final SqmPluralValuedSimplePath<?> mapPath = (SqmPluralValuedSimplePath<?>) sqmPath;
|
||||
|
@ -4630,6 +4670,18 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
return result;
|
||||
}
|
||||
|
||||
private void checkPluralPath(SqmPath<?> pluralAttributePath, SqmPathSource<?> referencedPathSource, TerminalNode firstNode) {
|
||||
if ( !(referencedPathSource instanceof PluralPersistentAttribute<?, ?, ?> ) ) {
|
||||
throw new PathException(
|
||||
String.format(
|
||||
"Argument of '%s' is not a plural path '%s'",
|
||||
firstNode.getSymbol().getText(),
|
||||
pluralAttributePath.getNavigablePath()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private <X> SqmPath<X> consumeDomainPath(HqlParser.PathContext parserPath) {
|
||||
final SemanticPathPart consumedPart = (SemanticPathPart) parserPath.accept( this );
|
||||
if ( consumedPart instanceof SqmPath ) {
|
||||
|
@ -4667,7 +4719,8 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
return sqmPath;
|
||||
}
|
||||
|
||||
throw new SemanticException( "Expecting plural attribute valued path [" + sqmPath.getNavigablePath() + "], but found : " + sqmPath.getReferencedPathSource().getSqmPathType() );
|
||||
throw new SemanticException( "Expecting plural attribute valued path [" + sqmPath.getNavigablePath() + "], but found : "
|
||||
+ sqmPath.getReferencedPathSource().getSqmPathType() );
|
||||
}
|
||||
|
||||
private void checkFQNEntityNameJpaComplianceViolationIfNeeded(String name, EntityDomainType<?> entityDescriptor) {
|
||||
|
|
|
@ -21,6 +21,7 @@ public class StrictJpaComplianceViolation extends SemanticException {
|
|||
FUNCTION_CALL( "improper non-standard function call" ),
|
||||
HQL_COLLECTION_FUNCTION( "use of HQL collection functions (maxelement, minelement, maxindex, minindex, elements, indices)"),
|
||||
VALUE_FUNCTION_ON_NON_MAP( "use of value() function for non-Map type" ),
|
||||
KEY_FUNCTION_ON_NON_MAP( "use of key() function for non-Map type" ),
|
||||
RESERVED_WORD_USED_AS_ALIAS( "use of reserved word as alias (identification variable or result variable)" ),
|
||||
INDEXED_ELEMENT_REFERENCE( "use of HQL indexed element reference syntax" ),
|
||||
TUPLES( "use of tuples/row value constructors" ),
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.testing.orm.domain.StandardDomainModel;
|
|||
import org.hibernate.testing.orm.domain.gambit.EntityOfBasics;
|
||||
import org.hibernate.testing.orm.domain.gambit.EntityOfLists;
|
||||
import org.hibernate.testing.orm.domain.gambit.EntityOfMaps;
|
||||
import org.hibernate.testing.orm.domain.gambit.SimpleEntity;
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||
|
@ -66,6 +67,12 @@ public class FunctionTests {
|
|||
eol.addBasic("hello");
|
||||
eol.addNumber(1.0);
|
||||
eol.addNumber(2.0);
|
||||
SimpleEntity hello = new SimpleEntity(3, "hello", 5L, 7);
|
||||
SimpleEntity goodbye = new SimpleEntity(6, "goodbye", 10L, 9);
|
||||
em.persist(hello);
|
||||
em.persist(goodbye);
|
||||
eol.addOneToMany(hello);
|
||||
eol.addManyToMany(goodbye);
|
||||
em.persist(eol);
|
||||
|
||||
EntityOfMaps eom = new EntityOfMaps(2,"");
|
||||
|
@ -89,85 +96,112 @@ public class FunctionTests {
|
|||
}
|
||||
);
|
||||
}
|
||||
//
|
||||
// @Test
|
||||
// public void testMaxMinSumIndexElement(SessionFactoryScope scope) {
|
||||
// scope.inTransaction(
|
||||
// session -> {
|
||||
// assertThat( session.createQuery("select max(index eol.listOfNumbers) from EntityOfLists eol")
|
||||
// .getSingleResult(), is(1) );
|
||||
// assertThat( session.createQuery("select max(element eol.listOfNumbers) from EntityOfLists eol")
|
||||
// .getSingleResult(), is(2.0) );
|
||||
//
|
||||
// assertThat( session.createQuery("select sum(index eol.listOfNumbers) from EntityOfLists eol")
|
||||
// .getSingleResult(), is(1) );
|
||||
// assertThat( session.createQuery("select sum(element eol.listOfNumbers) from EntityOfLists eol")
|
||||
// .getSingleResult(), is(3.0) );
|
||||
//
|
||||
// //TODO: why does this fail??
|
||||
//// assertThat( session.createQuery("select avg(index eol.listOfNumbers) from EntityOfLists eol")
|
||||
//// .getSingleResult(), is(0.5) );
|
||||
// assertThat( session.createQuery("select avg(element eol.listOfNumbers) from EntityOfLists eol")
|
||||
// .getSingleResult(), is(1.5) );
|
||||
//
|
||||
// assertThat( session.createQuery("select max(index eom.numberByNumber) from EntityOfMaps eom")
|
||||
// .getSingleResult(), is(1) );
|
||||
// assertThat( session.createQuery("select max(element eom.numberByNumber) from EntityOfMaps eom")
|
||||
// .getSingleResult(), is(1.0) );
|
||||
//
|
||||
// assertThat( session.createQuery("select sum(index eom.numberByNumber) from EntityOfMaps eom")
|
||||
// .getSingleResult(), is(1) );
|
||||
// assertThat( session.createQuery("select sum(element eom.numberByNumber) from EntityOfMaps eom")
|
||||
// .getSingleResult(), is(1.0) );
|
||||
//
|
||||
// assertThat( session.createQuery("select avg(index eom.numberByNumber) from EntityOfMaps eom")
|
||||
// .getSingleResult(), is(1) );
|
||||
// assertThat( session.createQuery("select avg(element eom.numberByNumber) from EntityOfMaps eom")
|
||||
// .getSingleResult(), is(1.0) );
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
//
|
||||
|
||||
@Test
|
||||
public void testAltMaxMinSumIndexElement(SessionFactoryScope scope) {
|
||||
//TODO: make the commented tests work!
|
||||
public void testImplicitCollectionJoinInSelect(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
// assertThat( session.createQuery("select max(index(eol.listOfNumbers)) from EntityOfLists eol group by eol")
|
||||
// .getSingleResult(), is(1) );
|
||||
assertThat( session.createQuery("select index(eol.listOfNumbers) from EntityOfLists eol", Integer.class)
|
||||
.getResultList(), hasItems(0,1) );
|
||||
assertThat( session.createQuery("select element(eol.listOfNumbers) from EntityOfLists eol", Double.class)
|
||||
.getResultList(), hasItems(1.0, 2.0) );
|
||||
|
||||
assertThat( session.createQuery("select key(eom.numberByNumber) from EntityOfMaps eom", Integer.class)
|
||||
.getResultList(), hasItems(1) );
|
||||
assertThat( session.createQuery("select value(eom.numberByNumber) from EntityOfMaps eom", Double.class)
|
||||
.getResultList(), hasItems(1.0) );
|
||||
|
||||
assertThat( session.createQuery("select key(eom.basicByBasic) from EntityOfMaps eom", String.class)
|
||||
.getResultList(), hasItems("hello") );
|
||||
assertThat( session.createQuery("select value(eom.basicByBasic) from EntityOfMaps eom", String.class)
|
||||
.getResultList(), hasItems("world") );
|
||||
|
||||
assertThat( session.createQuery("select element(eol.listOfOneToMany) from EntityOfLists eol", SimpleEntity.class).getSingleResult().getId(), is(3) ) ;
|
||||
assertThat( session.createQuery("select element(eol.listOfManyToMany) from EntityOfLists eol", SimpleEntity.class).getSingleResult().getId(), is(6) );
|
||||
|
||||
assertThat( session.createQuery("select element(se).someLong from EntityOfLists eol join eol.listOfOneToMany se", Long.class)
|
||||
.getSingleResult(), is(5L) );
|
||||
assertThat( session.createQuery("select element(eol.listOfOneToMany).someLong from EntityOfLists eol", Long.class)
|
||||
.getSingleResult(), is(5L) );
|
||||
|
||||
assertThat( session.createQuery("select element(se).someLong from EntityOfLists eol join eol.listOfManyToMany se", Long.class)
|
||||
.getSingleResult(), is(10L) );
|
||||
assertThat( session.createQuery("select element(eol.listOfManyToMany).someLong from EntityOfLists eol", Long.class)
|
||||
.getSingleResult(), is(10L) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImplicitCollectionJoinInWhere(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery("from EntityOfLists eol where index(eol.listOfNumbers)=0")
|
||||
.getResultList();
|
||||
session.createQuery("from EntityOfLists eol where element(eol.listOfNumbers)=1.0")
|
||||
.getResultList();
|
||||
|
||||
session.createQuery("from EntityOfMaps eom where key(eom.numberByNumber)=1")
|
||||
.getResultList();
|
||||
session.createQuery("from EntityOfMaps eom where value(eom.numberByNumber)=1.0")
|
||||
.getResultList();
|
||||
|
||||
session.createQuery("from EntityOfMaps eom where key(eom.basicByBasic)='hello'")
|
||||
.getResultList();
|
||||
session.createQuery("from EntityOfMaps eom where value(eom.basicByBasic)='world'")
|
||||
.getResultList();
|
||||
|
||||
session.createQuery("from EntityOfLists eol join eol.listOfOneToMany se where element(se).someLong=5")
|
||||
.getSingleResult();
|
||||
session.createQuery("from EntityOfLists eol where element(eol.listOfOneToMany).someLong=5")
|
||||
.getSingleResult();
|
||||
session.createQuery("from EntityOfLists eol join eol.listOfManyToMany se where element(se).someLong=10")
|
||||
.getSingleResult();
|
||||
session.createQuery("from EntityOfLists eol where element(eol.listOfManyToMany).someLong=10")
|
||||
.getSingleResult();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImplicitCollectionJoinInSelectAggregate(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
assertThat( session.createQuery("select max(index(eol.listOfNumbers)) from EntityOfLists eol group by eol")
|
||||
.getSingleResult(), is(1) );
|
||||
assertThat( session.createQuery("select max(element(eol.listOfNumbers)) from EntityOfLists eol group by eol")
|
||||
.getSingleResult(), is(2.0) );
|
||||
|
||||
// assertThat( session.createQuery("select sum(index(eol.listOfNumbers)) from EntityOfLists eol group by eol")
|
||||
// .getSingleResult(), is(1) );
|
||||
assertThat( session.createQuery("select sum(index(eol.listOfNumbers)) from EntityOfLists eol group by eol")
|
||||
.getSingleResult(), is(1L) );
|
||||
assertThat( session.createQuery("select sum(element(eol.listOfNumbers)) from EntityOfLists eol group by eol")
|
||||
.getSingleResult(), is(3.0) );
|
||||
|
||||
// assertThat( session.createQuery("select avg(index(eol.listOfNumbers)) from EntityOfLists eol group by eol")
|
||||
// .getSingleResult(), is(0.5) );
|
||||
assertThat( session.createQuery("select avg(index(eol.listOfNumbers)) from EntityOfLists eol group by eol")
|
||||
.getSingleResult(), is(0.5) );
|
||||
assertThat( session.createQuery("select avg(element(eol.listOfNumbers)) from EntityOfLists eol group by eol")
|
||||
.getSingleResult(), is(1.5) );
|
||||
|
||||
// assertThat( session.createQuery("select max(index(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
// .getSingleResult(), is(1) );
|
||||
assertThat( session.createQuery("select max(element(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
assertThat( session.createQuery("select max(key(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
.getSingleResult(), is(1) );
|
||||
assertThat( session.createQuery("select max(value(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
|
||||
// assertThat( session.createQuery("select sum(index(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
// .getSingleResult(), is(1) );
|
||||
assertThat( session.createQuery("select sum(element(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
assertThat( session.createQuery("select sum(key(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
.getSingleResult(), is(1L) );
|
||||
assertThat( session.createQuery("select sum(value(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
|
||||
// assertThat( session.createQuery("select avg(index(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
// .getSingleResult(), is(1) );
|
||||
assertThat( session.createQuery("select avg(element(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
assertThat( session.createQuery("select avg(key(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
assertThat( session.createQuery("select avg(value(eom.numberByNumber)) from EntityOfMaps eom group by eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxMinSumIndicesElements(SessionFactoryScope scope) {
|
||||
public void testAggregateIndicesElementsWithPath(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
assertThat( session.createQuery("select max(indices(eol.listOfNumbers)) from EntityOfLists eol")
|
||||
|
@ -176,12 +210,12 @@ public class FunctionTests {
|
|||
.getSingleResult(), is(2.0) );
|
||||
|
||||
assertThat( session.createQuery("select sum(indices(eol.listOfNumbers)) from EntityOfLists eol")
|
||||
.getSingleResult(), is(1) ); //TODO: should be Long
|
||||
.getSingleResult(), is(1L) );
|
||||
assertThat( session.createQuery("select sum(elements(eol.listOfNumbers)) from EntityOfLists eol")
|
||||
.getSingleResult(), is(3.0) );
|
||||
|
||||
// assertThat( session.createQuery("select avg(indices(eol.listOfNumbers)) from EntityOfLists eol")
|
||||
// .getSingleResult(), is(0.5) ); //TODO: FIX!!
|
||||
assertThat( session.createQuery("select avg(indices(eol.listOfNumbers)) from EntityOfLists eol")
|
||||
.getSingleResult(), is(0.5) );
|
||||
assertThat( session.createQuery("select avg(elements(eol.listOfNumbers)) from EntityOfLists eol")
|
||||
.getSingleResult(), is(1.5) );
|
||||
|
||||
|
@ -191,12 +225,12 @@ public class FunctionTests {
|
|||
.getSingleResult(), is(1.0) );
|
||||
|
||||
assertThat( session.createQuery("select sum(indices(eom.numberByNumber)) from EntityOfMaps eom")
|
||||
.getSingleResult(), is(1) ); //TODO: should be Long
|
||||
.getSingleResult(), is(1L) );
|
||||
assertThat( session.createQuery("select sum(elements(eom.numberByNumber)) from EntityOfMaps eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
|
||||
assertThat( session.createQuery("select avg(indices(eom.numberByNumber)) from EntityOfMaps eom")
|
||||
.getSingleResult(), is(1) ); //TODO: should be Double
|
||||
.getSingleResult(), is(1.0) );
|
||||
assertThat( session.createQuery("select avg(elements(eom.numberByNumber)) from EntityOfMaps eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
}
|
||||
|
@ -204,7 +238,7 @@ public class FunctionTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testNoMaxMinSumIndexElement(SessionFactoryScope scope) {
|
||||
public void testAggregateIndexElementKeyValueWithAlias(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
assertThat( session.createQuery("select max(index(l)) from EntityOfLists eol join eol.listOfNumbers l group by eol")
|
||||
|
@ -222,19 +256,19 @@ public class FunctionTests {
|
|||
assertThat( session.createQuery("select avg(element(l)) from EntityOfLists eol join eol.listOfNumbers l group by eol")
|
||||
.getSingleResult(), is(1.5) );
|
||||
|
||||
assertThat( session.createQuery("select max(index(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
assertThat( session.createQuery("select max(key(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
.getSingleResult(), is(1) );
|
||||
assertThat( session.createQuery("select max(element(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
assertThat( session.createQuery("select max(value(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
|
||||
assertThat( session.createQuery("select sum(index(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
assertThat( session.createQuery("select sum(key(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
.getSingleResult(), is(1L) );
|
||||
assertThat( session.createQuery("select sum(element(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
assertThat( session.createQuery("select sum(value(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
|
||||
assertThat( session.createQuery("select avg(index(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
assertThat( session.createQuery("select avg(key(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
assertThat( session.createQuery("select avg(element(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
assertThat( session.createQuery("select avg(value(m)) from EntityOfMaps eom join eom.numberByNumber m group by eom")
|
||||
.getSingleResult(), is(1.0) );
|
||||
}
|
||||
);
|
||||
|
|
|
@ -50,6 +50,17 @@ public class SimpleEntity {
|
|||
this.someLong = someLong;
|
||||
}
|
||||
|
||||
public SimpleEntity(
|
||||
Integer id,
|
||||
String someString,
|
||||
Long someLong,
|
||||
Integer someInteger) {
|
||||
this.id = id;
|
||||
this.someString = someString;
|
||||
this.someLong = someLong;
|
||||
this.someInteger = someInteger;
|
||||
}
|
||||
|
||||
public SimpleEntity(
|
||||
Integer id,
|
||||
Date someDate,
|
||||
|
|
Loading…
Reference in New Issue