=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicatorService.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicatorService.java 2015-09-07 17:36:38 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicatorService.java 2015-09-07 20:02:22 +0000 @@ -142,6 +142,15 @@ * @return the SQL string. */ String getAnalyticsSQl( String expression, boolean ignoreMissingValues ); + + /** + * Returns a SQL clause which matches any value for the data elements and + * attributes in the given expression. + * + * @param expression the expression. + * @return the SQL string. + */ + String getAnyValueExistsClauseAnalyticsSql( String expression ); /** * Indicates whether the given program indicator expression is valid. === modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java' --- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java 2015-09-07 17:36:38 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java 2015-09-07 20:02:22 +0000 @@ -544,6 +544,16 @@ sql += "and (" + sqlFilter + ") "; } + if ( params.hasProgramIndicatorDimension() ) + { + String anyValueFilter = programIndicatorService.getAnyValueExistsClauseAnalyticsSql( params.getProgramIndicator().getExpression() ); + + if ( anyValueFilter != null ) + { + sql += "and (" + anyValueFilter + ") "; + } + } + // --------------------------------------------------------------------- // Coordinates // --------------------------------------------------------------------- === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java 2015-09-07 17:36:38 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java 2015-09-07 20:02:22 +0000 @@ -585,7 +585,29 @@ return TextUtils.appendTail( matcher, buffer ); } - + + @Override + public String getAnyValueExistsClauseAnalyticsSql( String expression ) + { + Set uids = ProgramIndicator.getDataElementAndAttributeIdentifiers( expression ); + + System.out.println(uids); + + if ( uids.isEmpty() ) + { + return null; + } + + String sql = ""; + + for ( String uid : uids ) + { + sql += statementBuilder.columnQuote( uid ) + " is not null or "; + } + + return TextUtils.removeLastOr( sql ).trim(); + } + @Override @Transactional public String expressionIsValid( String expression ) === modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java 2015-09-07 17:36:38 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java 2015-09-07 20:02:22 +0000 @@ -468,6 +468,15 @@ } @Test + public void testGetAnyValueExistsFilterAnalyticsSQl() + { + String expected = "\"GCyeKSqlpdk\" is not null or \"gAyeKSqlpdk\" is not null"; + String expression = "#{OXXcwl6aPCQ.GCyeKSqlpdk} - A{gAyeKSqlpdk}"; + + assertEquals( expected, programIndicatorService.getAnyValueExistsClauseAnalyticsSql( expression ) ); + } + + @Test public void testGetAnalyticsSQl() { String expected = "coalesce(\"" + deA.getUid() + "\",0) + coalesce(\"" + atA.getUid() + "\",0) > 10";