=== 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-10-12 11:46:32 +0000 +++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/JdbcEventAnalyticsManager.java 2015-10-12 15:02:17 +0000 @@ -56,6 +56,7 @@ import org.hisp.dhis.common.NameableObject; import org.hisp.dhis.common.QueryFilter; import org.hisp.dhis.common.QueryItem; +import org.hisp.dhis.commons.collection.ListUtils; import org.hisp.dhis.commons.util.ExpressionUtils; import org.hisp.dhis.commons.util.TextUtils; import org.hisp.dhis.jdbc.StatementBuilder; @@ -104,7 +105,7 @@ { String countClause = getAggregateClause( params ); - String sql = "select " + countClause + " as value," + getSelectColumns( params ) + " "; + String sql = "select " + countClause + " as value," + StringUtils.join( getSelectColumns( params ), "," ) + " "; // --------------------------------------------------------------------- // Criteria @@ -116,7 +117,7 @@ // Group by // --------------------------------------------------------------------- - sql += "group by " + getSelectColumns( params ) + " "; + sql += "group by " + StringUtils.join( getSelectColumns( params ), "," ) + " "; // --------------------------------------------------------------------- // Sort order @@ -217,7 +218,9 @@ { List fixedCols = Lists.newArrayList( "psi", "ps", "executiondate", "longitude", "latitude", "ouname", "oucode" ); - String sql = "select " + getSelectString( fixedCols ) + getSelectColumns( params ) + " "; + List selectCols = ListUtils.distinctUnion( fixedCols, getSelectColumns( params ) ); + + String sql = "select " + StringUtils.join( selectCols, "," ) + " "; // --------------------------------------------------------------------- // Criteria @@ -405,11 +408,11 @@ { if ( EventOutputType.TRACKED_ENTITY_INSTANCE.equals( outputType ) && params.isProgramRegistration() ) { - return Lists.newArrayList( "tei" ); + return Lists.newArrayList( statementBuilder.columnQuote( "tei" ) ); } else if ( EventOutputType.ENROLLMENT.equals( outputType ) ) { - return Lists.newArrayList( "pi" ); + return Lists.newArrayList( statementBuilder.columnQuote( "pi" ) ); } } @@ -418,15 +421,15 @@ /** * Returns the dynamic select columns. Dimensions come first and query items - * second. + * second. Program indicator expressions are converted to SQL expressions. */ - private String getSelectColumns( EventQueryParams params ) + private List getSelectColumns( EventQueryParams params ) { - String sql = ""; + List columns = Lists.newArrayList(); for ( DimensionalObject dimension : params.getDimensions() ) { - sql += statementBuilder.columnQuote( dimension.getDimensionName() ) + ","; + columns.add( statementBuilder.columnQuote( dimension.getDimensionName() ) ); } for ( QueryItem queryItem : params.getItems() ) @@ -435,17 +438,53 @@ { ProgramIndicator in = (ProgramIndicator) queryItem.getItem(); - sql += "(" + programIndicatorService.getAnalyticsSQl( in.getExpression() ) + "),"; + columns.add( "(" + programIndicatorService.getAnalyticsSQl( in.getExpression() ) + ")" ); } else { - sql += statementBuilder.columnQuote( queryItem.getItemName() ) + ","; + columns.add( statementBuilder.columnQuote( queryItem.getItemName() ) ); } } - return removeLastComma( sql ); + return columns; } + /** + * Returns the dynamic select columns. Dimensions come first and query items + * second. Program indicator expressions are exploded into attributes and + * data element identifiers. + */ + private List getPartitionSelectColumns( EventQueryParams params ) + { + List columns = Lists.newArrayList(); + + for ( DimensionalObject dimension : params.getDimensions() ) + { + columns.add( statementBuilder.columnQuote( dimension.getDimensionName() ) ); + } + + for ( QueryItem queryItem : params.getItems() ) + { + if ( queryItem.isProgramIndicator() ) + { + ProgramIndicator in = (ProgramIndicator) queryItem.getItem(); + + Set uids = ProgramIndicator.getDataElementAndAttributeIdentifiers( in.getExpression() ); + + for ( String uid : uids ) + { + columns.add( statementBuilder.columnQuote( uid ) ); + } + } + else + { + columns.add( statementBuilder.columnQuote( queryItem.getItemName() ) ); + } + } + + return columns; + } + private String getFromWhereClause( EventQueryParams params, List fixedColumns ) { if ( params.spansMultiplePartitions() ) @@ -460,15 +499,17 @@ private String getFromWhereMultiplePartitionsClause( EventQueryParams params, List fixedColumns ) { - List aggregateCols = getAggregateColumns( params ); + List cols = ListUtils.distinctUnion( fixedColumns, getAggregateColumns( params ), getPartitionSelectColumns( params ) ); + + String selectCols = StringUtils.join( cols, "," ); String sql = "from ("; for ( String partition : params.getPartitions().getPartitions() ) { - sql += "select " + getSelectString( fixedColumns ) + getSelectString( aggregateCols ) + getSelectColumns( params ); + sql += "select " + selectCols + " "; - sql += " " + getFromWhereSinglePartitionClause( params, partition ); + sql += getFromWhereSinglePartitionClause( params, partition ); sql += "union all "; } @@ -630,22 +671,6 @@ } /** - * Creates a comma separated string based on the items in the given lists. - * Appends a comma at the end of the string if not empty. - */ - private String getSelectString( List columns ) - { - if ( columns == null || columns.isEmpty() ) - { - return StringUtils.EMPTY; - } - - String fixedCols = StringUtils.join( columns, ", " ); - - return StringUtils.defaultIfEmpty( fixedCols + ", ", fixedCols ); - } - - /** * Returns an item value for the given query, query item and value. Assumes that * data dimensions are collapsed for the given query. Returns the short name * of the given query item followed by the item value. If the given query item === modified file 'dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/collection/ListUtils.java' --- dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/collection/ListUtils.java 2015-10-01 13:57:42 +0000 +++ dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/collection/ListUtils.java 2015-10-12 15:02:17 +0000 @@ -253,6 +253,26 @@ return union; } + + /** + * Unions the given array of lists into a single list with distinct items. + * + * @param type. + * @param lists the array of lists. + * @return a union of the given lists. + */ + @SafeVarargs + public static final List distinctUnion( final List... lists ) + { + final List union = new UniqueArrayList<>(); + + for ( List list : lists ) + { + union.addAll( list ); + } + + return union; + } /** * Returns a contiguous list of Integers starting on and including a, ending