Skip to content

Commit e0759e2

Browse files
committed
Handle multiple jointures in subqueries
1 parent b711919 commit e0759e2

File tree

4 files changed

+52
-4
lines changed

4 files changed

+52
-4
lines changed

gemma-core/src/main/java/ubic/gemma/persistence/service/AbstractFilteringVoEnabledDao.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package ubic.gemma.persistence.service;
22

3-
import lombok.*;
3+
import lombok.EqualsAndHashCode;
4+
import lombok.Value;
5+
import lombok.With;
46
import org.apache.commons.collections4.CollectionUtils;
57
import org.apache.commons.lang3.ArrayUtils;
68
import org.apache.commons.lang3.time.StopWatch;
@@ -330,7 +332,17 @@ private Filter nestIfSubquery( Filter f, String propertyName ) {
330332
for ( FilterablePropertyAlias fpa : filterablePropertyAliases ) {
331333
if ( f.getObjectAlias().equals( fpa.getObjectAlias() ) ) {
332334
// FIXME: the prefix is not always a valid path
333-
aliases = Collections.singletonList( new Subquery.Alias( fpa.prefix.substring( 0, fpa.prefix.length() - 1 ), fpa.getObjectAlias() ) );
335+
String[] parts = fpa.prefix.split( "\\." );
336+
aliases = new ArrayList<>();
337+
for ( int i = 0; i < parts.length - 1; i++ ) {
338+
String part = parts[i];
339+
aliases.add( new Subquery.Alias( i > 0 ? "alias" + i : null, part, "alias" + ( i + 1 ) ) );
340+
}
341+
if ( parts.length > 1 ) {
342+
aliases.add( new Subquery.Alias( "alias" + ( parts.length - 1 ), parts[parts.length - 1], fpa.getObjectAlias() ) );
343+
} else {
344+
aliases.add( new Subquery.Alias( null, parts[0], fpa.getObjectAlias() ) );
345+
}
334346
break;
335347
}
336348
}

gemma-core/src/main/java/ubic/gemma/persistence/util/FilterQueryUtils.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,13 @@ private static String formSubClause( Filter filter, int i ) {
144144
.append( " " )
145145
.append( "e" );
146146
for ( Subquery.Alias a : s.getAliases() ) {
147-
disjunction.append( " join " ).append( "e." ).append( a.getPropertyName() ).append( " " ).append( a.getAlias() );
147+
disjunction.append( " join " );
148+
if ( a.getObjectAlias() == null ) {
149+
disjunction.append( "e." );
150+
} else {
151+
disjunction.append( a.getObjectAlias() ).append( "." );
152+
}
153+
disjunction.append( a.getPropertyName() ).append( " " ).append( a.getAlias() );
148154
}
149155
disjunction.append( " where " );
150156
if ( s.getFilter().getObjectAlias() == null ) {

gemma-core/src/main/java/ubic/gemma/persistence/util/Subquery.java

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import lombok.Value;
44

5+
import javax.annotation.Nullable;
56
import java.util.List;
67

78
/**
@@ -14,6 +15,8 @@ public class Subquery {
1415

1516
@Value
1617
public static class Alias {
18+
@Nullable
19+
String objectAlias;
1720
String propertyName;
1821
String alias;
1922
}

gemma-core/src/test/java/ubic/gemma/persistence/service/expression/experiment/ExpressionExperimentDaoTest.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ public void testSubquery() {
180180
.hasFieldOrPropertyWithValue( "entityName", "ubic.gemma.model.expression.experiment.ExpressionExperiment" )
181181
.hasFieldOrPropertyWithValue( "identifierPropertyName", "id" );
182182
Assertions.assertThat( s.getAliases() )
183-
.contains( new Subquery.Alias( "allCharacteristics", "ac" ) );
183+
.contains( new Subquery.Alias( null, "allCharacteristics", "ac" ) );
184184
Assertions.assertThat( s.getFilter() )
185185
.hasFieldOrPropertyWithValue( "objectAlias", "ac" )
186186
.hasFieldOrPropertyWithValue( "propertyName", "valueUri" )
@@ -191,6 +191,33 @@ public void testSubquery() {
191191
FilterQueryUtils.formRestrictionClause( Filters.by( f ) ) );
192192
}
193193

194+
@Test
195+
public void testSubqueryWithMultipleJointures() {
196+
Filter f = expressionExperimentDao.getFilter( "experimentalDesign.experimentalFactors.factorValues.characteristics.valueUri", Filter.Operator.in, Collections.singleton( "http://example.com" ) );
197+
Assertions.assertThat( f.getOperator() )
198+
.isEqualTo( Filter.Operator.inSubquery );
199+
Assertions.assertThat( f.getRequiredValue() )
200+
.isNotNull()
201+
.asInstanceOf( InstanceOfAssertFactories.type( Subquery.class ) )
202+
.satisfies( s -> {
203+
Assertions.assertThat( s )
204+
.hasFieldOrPropertyWithValue( "entityName", "ubic.gemma.model.expression.experiment.ExpressionExperiment" )
205+
.hasFieldOrPropertyWithValue( "identifierPropertyName", "id" );
206+
Assertions.assertThat( s.getAliases() )
207+
.containsExactly( new Subquery.Alias( null, "experimentalDesign", "alias1" ),
208+
new Subquery.Alias( "alias1", "experimentalFactors", "alias2" ),
209+
new Subquery.Alias( "alias2", "factorValues", "alias3" ),
210+
new Subquery.Alias( "alias3", "characteristics", "fvc" ) );
211+
Assertions.assertThat( s.getFilter() )
212+
.hasFieldOrPropertyWithValue( "objectAlias", "fvc" )
213+
.hasFieldOrPropertyWithValue( "propertyName", "valueUri" )
214+
.hasFieldOrPropertyWithValue( "operator", Filter.Operator.in )
215+
.hasFieldOrPropertyWithValue( "requiredValue", Collections.singletonList( "http://example.com" ) );
216+
} );
217+
// assertEquals( "and (ee.id in (select e.id from ubic.gemma.model.expression.experiment.ExpressionExperiment e join e.allCharacteristics ac where ac.valueUri in (:ac_valueUri1)))",
218+
// FilterQueryUtils.formRestrictionClause( Filters.by( f ) ) );
219+
}
220+
194221
private ExpressionExperiment reload( ExpressionExperiment e ) {
195222
sessionFactory.getCurrentSession().flush();
196223
sessionFactory.getCurrentSession().evict( e );

0 commit comments

Comments
 (0)