summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlzhang2011-12-13 23:18:37 (EST)
committer xgu2011-12-13 23:21:26 (EST)
commit8fbe0b7c2e637f0ff4c402d5fe27932ca2c181df (patch)
tree5b490f7a7c0cec68826db5e739856beb18ea5771
parent67536f2cc5c5aa726768507fba6086ec485ee912 (diff)
downloadorg.eclipse.birt-8fbe0b7c2e637f0ff4c402d5fe27932ca2c181df.zip
org.eclipse.birt-8fbe0b7c2e637f0ff4c402d5fe27932ca2c181df.tar.gz
org.eclipse.birt-8fbe0b7c2e637f0ff4c402d5fe27932ca2c181df.tar.bz2
Checkin: support step by step query execution for xTab
-rw-r--r--data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/AggregationResultSet.java10
-rw-r--r--data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggrMeasureFilterHelper.java99
-rw-r--r--data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggregationFilterHelper.java240
-rw-r--r--data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/impl/query/CubeQueryExecutor.java14
-rw-r--r--data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/query/view/QueryExecutor.java210
5 files changed, 558 insertions, 15 deletions
diff --git a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/AggregationResultSet.java b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/AggregationResultSet.java
index cd8915f..dcc43be 100644
--- a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/AggregationResultSet.java
+++ b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/AggregationResultSet.java
@@ -644,4 +644,14 @@ public class AggregationResultSet implements IAggregationResultSet
}
return null;
}
+
+ public IDiskArray getAggregationResultRows( )
+ {
+ return this.aggregationResultRows;
+ }
+
+ public void setAggregationResultRows( IDiskArray rows)
+ {
+ this.aggregationResultRows = rows;
+ }
}
diff --git a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggrMeasureFilterHelper.java b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggrMeasureFilterHelper.java
index 34c2b06..b982d04 100644
--- a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggrMeasureFilterHelper.java
+++ b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggrMeasureFilterHelper.java
@@ -30,12 +30,16 @@ import org.eclipse.birt.data.engine.olap.data.api.cube.ICube;
import org.eclipse.birt.data.engine.olap.data.api.cube.IDimension;
import org.eclipse.birt.data.engine.olap.data.impl.AggregationFunctionDefinition;
import org.eclipse.birt.data.engine.olap.data.impl.DrilledAggregationDefinition;
+import org.eclipse.birt.data.engine.olap.data.impl.aggregation.AggregationResultRow;
+import org.eclipse.birt.data.engine.olap.data.impl.aggregation.AggregationResultSet;
import org.eclipse.birt.data.engine.olap.data.impl.dimension.Dimension;
import org.eclipse.birt.data.engine.olap.data.impl.dimension.Level;
import org.eclipse.birt.data.engine.olap.data.util.BufferedPrimitiveDiskArray;
+import org.eclipse.birt.data.engine.olap.data.util.BufferedStructureArray;
import org.eclipse.birt.data.engine.olap.data.util.IDiskArray;
import org.eclipse.birt.data.engine.olap.data.util.SetUtil;
import org.eclipse.birt.data.engine.olap.util.OlapExpressionCompiler;
+import org.eclipse.birt.data.engine.olap.util.filter.AggrMeasureFilterEvalHelper;
import org.eclipse.birt.data.engine.olap.util.filter.CubePosFilter;
import org.eclipse.birt.data.engine.olap.util.filter.IAggrMeasureFilterEvalHelper;
import org.eclipse.birt.data.engine.olap.util.filter.InvalidCubePosFilter;
@@ -403,6 +407,101 @@ public class AggrMeasureFilterHelper
}
return result;
}
+
+ public IAggregationResultSet[] removeInvalidAggrRows ( List jsMeasureEvalFilterHelper, List<Integer> affectedAggrResultSetIndex ) throws DataException, IOException
+ {
+ IAggregationResultSet[] result = new IAggregationResultSet[resultSet.length];
+ String[] aggregationNames = populateAggregationNames( getAggregationName( ), jsMeasureEvalFilterHelper );
+ for ( int i = 0; i < resultSet.length; i++ )
+ {
+ if ( hasDefinition( resultSet[i], aggregationNames ) )
+ {
+ IDiskArray validRows = collectValidAggregationResultSetRows( resultSet[i], jsMeasureEvalFilterHelper, aggregationNames );
+ IAggregationResultSet newAggrResultSet = new AggregationResultSet( resultSet[i].getAggregationDefinition( ),
+ resultSet[i].getAllLevels( ), validRows,
+ resultSet[i].getKeyNames( ), resultSet[i].getAttributeNames( ) );
+ result[i] = newAggrResultSet;
+ affectedAggrResultSetIndex.add( Integer.valueOf( i ) );
+ }
+ else
+ {
+ result[i] = resultSet[i];
+ }
+ }
+
+ return result;
+ }
+
+ private IDiskArray collectValidAggregationResultSetRows(
+ IAggregationResultSet resultSet, List filterHelpers,
+ String[] aggregationNames ) throws DataException, IOException
+ {
+ IDiskArray result = new BufferedStructureArray( AggregationResultRow.getCreator( ), resultSet.length( ) );
+ AggregationRowAccessor rowAccessor = new AggregationRowAccessor( resultSet, null );
+ List<IAggrMeasureFilterEvalHelper> firstRoundFilterHelper = new ArrayList<IAggrMeasureFilterEvalHelper>();
+
+ FilterPassController filterPassController = new FilterPassController();
+ for ( int j = 0; j < filterHelpers.size( ); j++ )
+ {
+ if ( resultSet.getAggregationIndex( aggregationNames[j] ) >= 0 )
+ {
+ IAggrMeasureFilterEvalHelper filterHelper = (IAggrMeasureFilterEvalHelper) filterHelpers.get( j );
+ if( isTopBottomNConditionalExpression( filterHelper.getExpression()))
+ {
+ IConditionalExpression expr = (IConditionalExpression)filterHelper.getExpression( );
+ firstRoundFilterHelper.add( filterHelper );
+ expr.setHandle( NEvaluator.newInstance( PropertySecurity.getSystemProperty( "java.io.tmpdir" ),
+ expr.getOperator( ),
+ expr.getExpression( ),
+ (IScriptExpression)expr.getOperand1( ),
+ filterPassController ) );
+ }
+ }
+ }
+
+ filterPassController.setPassLevel( FilterPassController.FIRST_PASS );
+ filterPassController.setRowCount( resultSet.length());
+ if ( firstRoundFilterHelper.size( ) > 0 )
+ {
+ for ( int i = 0; i < resultSet.length( ); i++ )
+ {
+ resultSet.seek( i );
+ for ( int j = 0; j < firstRoundFilterHelper.size( ); j++ )
+ {
+ firstRoundFilterHelper.get( j )
+ .evaluateFilter( rowAccessor );
+ }
+ }
+ }
+
+ filterPassController.setPassLevel( FilterPassController.SECOND_PASS );
+
+ for ( int i = 0; i < resultSet.length( ); i++ )
+ {
+ resultSet.seek( i );
+ boolean isFilterByAll = true;
+
+ for ( int j = 0; j < filterHelpers.size( ); j++ )
+ {
+ if ( resultSet.getAggregationIndex( aggregationNames[j] ) >= 0 )
+ {
+ AggrMeasureFilterEvalHelper filterHelper = (AggrMeasureFilterEvalHelper) filterHelpers.get( j );
+ if ( !filterHelper.evaluateFilter( rowAccessor ) )
+ {
+ isFilterByAll = false;
+ break;
+ }
+ }
+ }
+
+ if ( isFilterByAll )
+ {
+ result.add( resultSet.getCurrentRow( ) );
+ }
+ }
+
+ return result;
+ }
private boolean isTopBottomNConditionalExpression( IBaseExpression expr )
{
diff --git a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggregationFilterHelper.java b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggregationFilterHelper.java
index 33b75c5..acc166b 100644
--- a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggregationFilterHelper.java
+++ b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/data/impl/aggregation/filter/AggregationFilterHelper.java
@@ -23,6 +23,7 @@ import org.eclipse.birt.data.engine.core.DataException;
import org.eclipse.birt.data.engine.olap.api.query.ICubeFilterDefinition;
import org.eclipse.birt.data.engine.olap.api.query.ILevelDefinition;
import org.eclipse.birt.data.engine.olap.data.api.DimLevel;
+import org.eclipse.birt.data.engine.olap.data.api.IAggregationResultRow;
import org.eclipse.birt.data.engine.olap.data.api.IAggregationResultSet;
import org.eclipse.birt.data.engine.olap.data.api.IBindingValueFetcher;
import org.eclipse.birt.data.engine.olap.data.api.ILevel;
@@ -31,8 +32,11 @@ import org.eclipse.birt.data.engine.olap.data.api.cube.IDimension;
import org.eclipse.birt.data.engine.olap.data.impl.AggregationDefinition;
import org.eclipse.birt.data.engine.olap.data.impl.Cube;
import org.eclipse.birt.data.engine.olap.data.impl.SelectionFactory;
+import org.eclipse.birt.data.engine.olap.data.impl.aggregation.AggregationResultRow;
+import org.eclipse.birt.data.engine.olap.data.impl.aggregation.AggregationResultSet;
import org.eclipse.birt.data.engine.olap.data.impl.dimension.Member;
import org.eclipse.birt.data.engine.olap.data.util.BufferedPrimitiveDiskArray;
+import org.eclipse.birt.data.engine.olap.data.util.BufferedStructureArray;
import org.eclipse.birt.data.engine.olap.data.util.CompareUtil;
import org.eclipse.birt.data.engine.olap.data.util.IDiskArray;
import org.eclipse.birt.data.engine.olap.data.util.ObjectArrayUtil;
@@ -252,6 +256,242 @@ public class AggregationFilterHelper
levelFilters.add( levelFilter );
}
}
+
+ private boolean hasFiltersOnEdgeAggrResultSet( IAggregationResultSet rs )
+ {
+ boolean result = false;
+
+ for ( int k = 0; k < this.topbottomFilters.size( ); k++ )
+ {
+ TopBottomFilterDefinition filterDefinition = (TopBottomFilterDefinition) topbottomFilters.get( k );
+ if ( isMatch( rs.getAggregationDefinition( ), rs, filterDefinition ) )
+ return true;
+ }
+
+ for ( int k = 0; k < this.aggrFilters.size( ); k++ )
+ {
+ AggrFilterDefinition filterDefinition = ( (AggrFilterDefinition) aggrFilters.get( k ) );
+ if ( isMatch( rs.getAggregationDefinition( ), rs, filterDefinition ) )
+ return true;
+ }
+
+ return result;
+ }
+
+ private List populateDistinctLevelKeyList(
+ AggregationDefinition aggregation, IAggregationResultSet resultSet,
+ TopBottomFilterDefinition filter ) throws DataException
+ {
+ IJSTopBottomFilterHelper filterHelper = (IJSTopBottomFilterHelper) filter.getFilterHelper( );
+ int n = -1;
+ if ( filterHelper.isPercent( ) == false )
+ {
+ n = (int) filterHelper.getN( );
+ }
+
+ IDiskArray aggrValueArray = new OrderedDiskArray( n,
+ filterHelper.isTop( ) );
+
+ String dimensionName = filter.getTargetLevel( ).getDimensionName( );
+ Object preValue = null ;
+ try
+ {
+ AggregationRowAccessor row4filter = new AggregationRowAccessor( resultSet,
+ fetcher );
+ for ( int k = 0; k < resultSet.length( ); k++ )
+ {
+ resultSet.seek( k );
+ int levelIndex = resultSet.getLevelIndex( filter.getTargetLevel( ) );
+ Object[] levelKey = resultSet.getLevelKeyValue( levelIndex );
+ Object aggrValue = filterHelper.evaluateFilterExpr( row4filter );
+ if ( levelKey != null
+ && filterHelper.isQualifiedRow( row4filter )
+ && ( CompareUtil.compare( preValue, aggrValue ) != 0 ) )
+ {
+ aggrValueArray.add( aggrValue );
+ }
+ preValue = aggrValue;
+ }
+ return fetchDistictLevelKeys( aggrValueArray, filterHelper );
+ }
+ catch ( IOException e )
+ {
+ throw new DataException( "", e );//$NON-NLS-1$
+ }
+
+ }
+
+ private List fetchDistictLevelKeys( IDiskArray aggrValueArray,
+ IJSTopBottomFilterHelper filterHelper ) throws IOException
+ {
+ int start = 0; // level key start index in aggrValueArray
+ int end = aggrValueArray.size( ); // level key end index (not
+ // including) in aggrValueArray
+ if ( filterHelper.isPercent( ) )
+ {// top/bottom percentage filter
+ int size = aggrValueArray.size( ); // target level member size
+ int n = FilterUtil.getTargetN( size, filterHelper.getN( ) );
+ if ( filterHelper.isTop( ) )
+ start = size - n;
+ else
+ end = n;
+ }
+ List resultList = new ArrayList();
+ for ( int i = start; i < end; i++ )
+ {
+ Object aggrValue = aggrValueArray.get( i );
+ resultList.add( aggrValue );
+ }
+ return resultList;
+ }
+
+ public IAggregationResultSet[] generateFilteredAggregationResultSet ( IAggregationResultSet[] rs,List<Integer> affectedAggrResultSetIndex ) throws IOException, DataException
+ {
+ IAggregationResultSet[] result = new AggregationResultSet[rs.length];
+ List levelFilterList = new ArrayList( );
+ for ( int i = 0; i < rs.length; i++ )
+ {
+ if ( rs[i].getAggregationDefinition( ).getAggregationFunctions( ) == null && hasFiltersOnEdgeAggrResultSet( rs[i] ) )
+ {
+ AggregationRowAccessor row4filter = new AggregationRowAccessor( rs[i], fetcher );
+ IDiskArray validRows = new BufferedStructureArray( AggregationResultRow.getCreator(),rs[i].length());
+ List[] topBottomNFilterResultList = null;
+ int[] targetLevelIndex = null;
+ if ( this.topbottomFilters.size( ) > 0 )
+ {
+ topBottomNFilterResultList = new List[this.topbottomFilters.size( )];
+ targetLevelIndex = new int[this.topbottomFilters.size( )];
+ }
+
+ for ( int k = 0; k < this.topbottomFilters.size( ); k++ )
+ {
+ IJSTopBottomFilterHelper filterHelper = (IJSTopBottomFilterHelper) ( (TopBottomFilterDefinition) topbottomFilters.get( k ) ).getFilterHelper( );
+ topBottomNFilterResultList[k] = populateDistinctLevelKeyList( rs[i].getAggregationDefinition( ),
+ rs[i],
+ (TopBottomFilterDefinition) topbottomFilters.get( k ) );
+ targetLevelIndex[k] = rs[i].getLevelIndex( ((TopBottomFilterDefinition) topbottomFilters.get( k ) ).getTargetLevel( ));
+ }
+
+ for ( int j = 0; j < rs[i].length( ); j++ )
+ {
+ rs[i].seek( j );
+ boolean isFilterByAll = true;
+
+ for ( int k = 0; k < this.aggrFilters.size( ); k++ )
+ {
+ IJSDimensionFilterHelper filterHelper = (IJSDimensionFilterHelper) ( (AggrFilterDefinition) aggrFilters.get( k ) ).getFilterHelper( );
+ if ( !filterHelper.evaluateFilter( row4filter ) )
+ {
+ isFilterByAll = false;
+ break;
+ }
+ }
+
+ for ( int k = 0; k < this.topbottomFilters.size( ); k++ )
+ {
+ IAggregationResultRow currentRow = rs[i].getCurrentRow( );
+ if ( targetLevelIndex[k] >= 0 )
+ {
+ Member m = currentRow.getLevelMembers( )[targetLevelIndex[k]];
+ if ( !topBottomNFilterResultList[k].contains( m.getKeyValues( )[0] ) )
+ {
+ isFilterByAll = false;
+ break;
+ }
+ }
+ }
+
+ if ( isFilterByAll )
+ {
+ validRows.add( rs[i].getCurrentRow() );
+ }
+ }
+
+ IAggregationResultSet newAggrResultSet = new AggregationResultSet(rs[i].getAggregationDefinition( ),
+ rs[i].getAllLevels( ), validRows,
+ rs[i].getKeyNames( ), rs[i].getAttributeNames( ));
+ result[i] = newAggrResultSet;
+ }
+ else
+ {
+ boolean filtered = false;
+ for ( Iterator k = aggrFilters.iterator( ); k.hasNext( ); )
+ {
+ AggrFilterDefinition filter = (AggrFilterDefinition) k.next( );
+ if ( rs[i].getAggregationDefinition( )
+ .getAggregationFunctions( ) != null
+ && isMatch( rs[i].getAggregationDefinition( ),
+ rs[i],
+ filter ) && filter.getAxisQualifierLevels( )!=null )
+ {
+ applyAggrFilter( rs[i], filter, levelFilterList );
+ filtered = true;
+ }
+ }
+
+ for ( Iterator k = topbottomFilters.iterator( ); k.hasNext( ); )
+ {
+ TopBottomFilterDefinition filter = (TopBottomFilterDefinition) k.next( );
+ if ( rs[i].getAggregationDefinition( )
+ .getAggregationFunctions( ) != null
+ && isMatch( rs[i].getAggregationDefinition( ),
+ rs[i],
+ filter ) && filter.getAxisQualifierLevels( )!=null )
+ {
+ applyTopBottomFilters( new AggregationDefinition[]{
+ rs[i].getAggregationDefinition( )
+ }, new IAggregationResultSet[]{
+ rs[i]
+ }, levelFilterList );
+ filtered = true;
+ }
+ }
+
+ if ( filtered && levelFilterList.size( ) > 0 )
+ {
+ IDiskArray validRows = new BufferedStructureArray( AggregationResultRow.getCreator( ),
+ rs[i].length( ) );
+ for ( int k = 0; k < levelFilterList.size( ); k++ )
+ {
+ LevelFilter f = (LevelFilter) levelFilterList.get( k );
+ ISelection[] selections = f.getSelections( );
+
+ for ( int p = 0; p < selections.length; p++ )
+ {
+ ISelection select = selections[p];
+ DimLevel dim = new DimLevel( f.getDimensionName( ),
+ f.getLevelName( ) );
+ int levelIndex = rs[i].getLevelIndex( dim );
+ if ( levelIndex >= 0 )
+ {
+ for ( int m = 0; m < rs[i].length( ); m++ )
+ {
+ rs[i].seek( m );
+ Object[] obj = rs[i].getCurrentRow( )
+ .getLevelMembers( )[levelIndex].getKeyValues( );
+ if ( select.isSelected( obj ) )
+ {
+ validRows.add( rs[i].getCurrentRow( ) );
+ }
+ }
+ }
+ }
+ }
+ IAggregationResultSet newAggrResultSet = new AggregationResultSet(rs[i].getAggregationDefinition( ),
+ rs[i].getAllLevels( ), validRows,
+ rs[i].getKeyNames( ), rs[i].getAttributeNames( ));
+ result[i] = newAggrResultSet;
+ affectedAggrResultSetIndex.add( Integer.valueOf( i ) );
+ }
+ else
+ {
+ result[i] = rs[i];
+ }
+ }
+ }
+
+ return result;
+ }
/**
* get the members of the specified dimension from the aggregation result
diff --git a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/impl/query/CubeQueryExecutor.java b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/impl/query/CubeQueryExecutor.java
index 8148b0e..ac93ddc 100644
--- a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/impl/query/CubeQueryExecutor.java
+++ b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/impl/query/CubeQueryExecutor.java
@@ -81,9 +81,9 @@ public class CubeQueryExecutor
private List<IAggrMeasureFilterEvalHelper> aggrMeasureFilterEvalHelpers;
private List<IJSFacttableFilterEvalHelper> advancedFacttableBasedFilterEvalHelper;
- private static final int DIMENSION_FILTER = 0;
- private static final int AGGR_MEASURE_FILTER = 1;
- private static final int FACTTABLE_FILTER = 2;
+ public static final int DIMENSION_FILTER = 0;
+ public static final int AGGR_MEASURE_FILTER = 1;
+ public static final int FACTTABLE_FILTER = 2;
/**
*
* @param outResults
@@ -291,6 +291,10 @@ public class CubeQueryExecutor
for ( int i = 0; i < filters.size( ); i++ )
{
IFilterDefinition filter = (IFilterDefinition) filters.get( i );
+ if ( !filter.updateAggregation( ) )
+ {
+ continue;
+ }
switch ( this.getFilterType( filter, dimLevelInCubeQuery ))
{
case CubeQueryExecutor.DIMENSION_FILTER:
@@ -343,7 +347,7 @@ public class CubeQueryExecutor
}
}
- private int getFilterType( IFilterDefinition filter, Set<DimLevel> dimLevelInCubeQuery ) throws DataException
+ public int getFilterType( IFilterDefinition filter, Set<DimLevel> dimLevelInCubeQuery ) throws DataException
{
if(! (filter instanceof ICubeFilterDefinition))
{
@@ -484,7 +488,7 @@ public class CubeQueryExecutor
return this.advancedFacttableBasedFilterEvalHelper;
}
- private Set<DimLevel> getDimLevelsDefinedInCubeQuery( )
+ public Set<DimLevel> getDimLevelsDefinedInCubeQuery( )
{
Set<DimLevel> dimLevelDefinedInCube = new HashSet<DimLevel>();
populateDimLevelInEdge( dimLevelDefinedInCube, ICubeQueryDefinition.COLUMN_EDGE );
diff --git a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/query/view/QueryExecutor.java b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/query/view/QueryExecutor.java
index 70b0ed0..6a4995e 100644
--- a/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/query/view/QueryExecutor.java
+++ b/data/org.eclipse.birt.data/src/org/eclipse/birt/data/engine/olap/query/view/QueryExecutor.java
@@ -15,6 +15,7 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import org.eclipse.birt.core.archive.FileArchiveReader;
@@ -23,6 +24,7 @@ import org.eclipse.birt.core.archive.compound.ArchiveWriter;
import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.data.engine.api.DataEngineContext;
import org.eclipse.birt.data.engine.api.IBinding;
+import org.eclipse.birt.data.engine.api.IFilterDefinition;
import org.eclipse.birt.data.engine.core.DataException;
import org.eclipse.birt.data.engine.core.security.FileSecurity;
import org.eclipse.birt.data.engine.executor.cache.CacheUtil;
@@ -42,12 +44,19 @@ import org.eclipse.birt.data.engine.olap.data.api.cube.ICube;
import org.eclipse.birt.data.engine.olap.data.impl.AggregationDefinition;
import org.eclipse.birt.data.engine.olap.data.impl.AggregationResultSetSaveUtil;
import org.eclipse.birt.data.engine.olap.data.impl.CachedAggregationResultSet;
+import org.eclipse.birt.data.engine.olap.data.impl.Cube;
import org.eclipse.birt.data.engine.olap.data.impl.DrilledAggregation;
import org.eclipse.birt.data.engine.olap.data.impl.DrilledAggregationDefinition;
+import org.eclipse.birt.data.engine.olap.data.impl.aggregation.AggregationResultRow;
import org.eclipse.birt.data.engine.olap.data.impl.aggregation.AggregationResultSet;
import org.eclipse.birt.data.engine.olap.data.impl.aggregation.SortedAggregationRowArray;
+import org.eclipse.birt.data.engine.olap.data.impl.aggregation.filter.AggrMeasureFilterHelper;
+import org.eclipse.birt.data.engine.olap.data.impl.aggregation.filter.AggregationFilterHelper;
import org.eclipse.birt.data.engine.olap.data.impl.aggregation.sort.AggrSortDefinition;
import org.eclipse.birt.data.engine.olap.data.impl.aggregation.sort.ITargetSort;
+import org.eclipse.birt.data.engine.olap.data.impl.dimension.Member;
+import org.eclipse.birt.data.engine.olap.data.util.BufferedStructureArray;
+import org.eclipse.birt.data.engine.olap.data.util.IDiskArray;
import org.eclipse.birt.data.engine.olap.driver.CubeResultSet;
import org.eclipse.birt.data.engine.olap.driver.IResultSet;
import org.eclipse.birt.data.engine.olap.impl.query.CubeOperationsExecutor;
@@ -56,10 +65,12 @@ import org.eclipse.birt.data.engine.olap.impl.query.CubeQueryExecutor;
import org.eclipse.birt.data.engine.olap.impl.query.IncrementExecutionHint;
import org.eclipse.birt.data.engine.olap.util.OlapExpressionCompiler;
import org.eclipse.birt.data.engine.olap.util.OlapExpressionUtil;
+import org.eclipse.birt.data.engine.olap.util.filter.AggrMeasureFilterEvalHelper;
+import org.eclipse.birt.data.engine.olap.util.filter.BaseDimensionFilterEvalHelper;
+import org.eclipse.birt.data.engine.olap.util.filter.IJSFilterHelper;
import org.eclipse.birt.data.engine.olap.util.sort.DimensionSortEvalHelper;
import org.eclipse.birt.data.engine.script.ScriptConstants;
import org.mozilla.javascript.Scriptable;
-
/**
*
*
@@ -142,8 +153,8 @@ public class QueryExecutor
{
rs = populateRs( view, finalAggregation, cubeQueryExecutorHelper,
stopSign,
- true );
-
+ true, fetcher );
+ rs = applyNoAggrUpdateFilters( executor, rs, cube, fetcher );
rs = processOperationOnQuery( view, stopSign, rs, aggrDefns );
break;
@@ -151,10 +162,10 @@ public class QueryExecutor
case DataEngineContext.DIRECT_PRESENTATION:
{
rs = populateRs( view, finalAggregation, cubeQueryExecutorHelper,
- stopSign, false );
-
+ stopSign, false, fetcher );
+ rs = applyNoAggrUpdateFilters( executor, rs, cube, fetcher );
rs = processOperationOnQuery( view, stopSign, rs, aggrDefns );
-
+
break;
}
case DataEngineContext.MODE_PRESENTATION:
@@ -178,6 +189,8 @@ public class QueryExecutor
else
{
rs = cubeQueryExecutorHelper.execute( finalAggregation, stopSign );
+ rs = applyNoAggrUpdateFilters( executor, rs, cube, fetcher );
+
//process mirror operation
MirrorOperationExecutor moe = new MirrorOperationExecutor( );
rs = moe.execute( rs, view, cubeQueryExecutorHelper );
@@ -210,6 +223,8 @@ public class QueryExecutor
{
//need to re-execute the query.
rs = cubeQueryExecutorHelper.execute( finalAggregation, stopSign );
+ rs = applyNoAggrUpdateFilters( executor, rs, cube, fetcher );
+
//process mirror operation
MirrorOperationExecutor moe = new MirrorOperationExecutor( );
rs = moe.execute( rs, view, cubeQueryExecutorHelper );
@@ -253,6 +268,180 @@ public class QueryExecutor
return new CubeResultSet( rs, view, cubeQueryExecutorHelper );
}
+
+ private IAggregationResultSet[] applyNoAggrUpdateFilters ( CubeQueryExecutor executor , IAggregationResultSet[] rs , ICube cube, IBindingValueFetcher fetcher ) throws DataException, IOException
+ {
+ List finalFilters = getNoAggrUpdateFilters( executor.getCubeQueryDefinition( ).getFilters( ) );
+ if( !finalFilters.isEmpty( ) )
+ {
+ List aggrEvalList = new ArrayList<AggrMeasureFilterEvalHelper>( );
+ List dimEvalList = new ArrayList<IJSFilterHelper>();
+ for ( int i = 0; i < finalFilters.size( ); i++ )
+ {
+ IFilterDefinition filter = (IFilterDefinition) finalFilters.get( i );
+ int type = executor.getFilterType( filter,
+ executor.getDimLevelsDefinedInCubeQuery( ) );
+
+ if ( type == executor.DIMENSION_FILTER )
+ {
+ dimEvalList.add( BaseDimensionFilterEvalHelper.createFilterHelper( executor.getOuterResults( ),
+ executor.getScope( ),
+ executor.getCubeQueryDefinition( ),
+ filter,
+ executor.getSession( )
+ .getEngineContext( )
+ .getScriptContext( ) ) );
+ }
+ else if ( type == executor.AGGR_MEASURE_FILTER )
+ {
+ aggrEvalList.add( new AggrMeasureFilterEvalHelper( executor.getOuterResults( ),
+ executor.getScope( ),
+ executor.getCubeQueryDefinition( ),
+ filter,
+ executor.getSession( )
+ .getEngineContext( )
+ .getScriptContext( ) ) );
+ }
+ }
+ List<Integer> affectedAggrResultSetIndex = new ArrayList<Integer>();
+ if( aggrEvalList.size( ) > 0)
+ {
+ AggrMeasureFilterHelper aggrFilterHelper = new AggrMeasureFilterHelper( cube,
+ rs );
+ rs = aggrFilterHelper.removeInvalidAggrRows( aggrEvalList, affectedAggrResultSetIndex );
+
+ }
+ if ( dimEvalList.size( ) > 0 )
+ {
+ AggregationFilterHelper helper = new AggregationFilterHelper( (Cube)cube, dimEvalList, fetcher );
+ rs = helper.generateFilteredAggregationResultSet( rs , affectedAggrResultSetIndex );
+ }
+ List<IAggregationResultSet> edgeResultSet = new ArrayList<IAggregationResultSet>();
+
+ for ( int i = 0; i < rs.length; i++ )
+ {
+ if ( rs[i].getAggregationDefinition( )
+ .getAggregationFunctions( ) == null )
+ {
+ edgeResultSet.add( rs[i] );
+ }
+ }
+ for ( int i = 0; i < edgeResultSet.size( ); i++ )
+ {
+ for ( int j = 0; j < affectedAggrResultSetIndex.size( ); j++ )
+ {
+ this.applyJoin( edgeResultSet.get( i ),
+ rs[affectedAggrResultSetIndex.get( j ).intValue( )] );
+ }
+ }
+ }
+
+ return rs;
+ }
+
+ private int getPos(String[][] joinLevelKeys, String[][] detailLevelKeys)
+ {
+ for (int i = 0; i < detailLevelKeys.length; i++)
+ {
+ if (joinLevelKeys[0].equals( detailLevelKeys[i] ))
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private void applyJoin(IAggregationResultSet joinRS, IAggregationResultSet detailRS) throws IOException
+ {
+ String[][] detailLevelKeys = detailRS.getLevelKeys( );
+ List<Members> detailMember = new ArrayList<Members>();
+ String[][] joinLevelKeys = null;
+ Member[] members = null;
+ IDiskArray aggregationResultRows = null;
+
+ joinLevelKeys = joinRS.getLevelKeys( );
+
+ int pos = getPos(joinLevelKeys, detailLevelKeys);
+
+ for (int index = 0; index < detailRS.length( ); index++)
+ {
+ detailRS.seek( index );
+ members = detailRS.getCurrentRow( ).getLevelMembers( );
+ if (members == null)
+ {
+ continue;
+ }
+ List<Member> tmpMembers = new ArrayList<Member>();
+ for (int j = pos; j < pos + joinLevelKeys.length; j++)
+ {
+ if ( j > members.length - 1)
+ {
+ break;
+ }
+ if (joinLevelKeys[j - pos].equals( detailLevelKeys[j] ))
+ {
+ tmpMembers.add (members[j]);
+ }
+
+ }
+ detailMember.add( new Members(tmpMembers.toArray( new Member[]{} )) );
+ }
+ Collections.sort( detailMember );
+
+ aggregationResultRows = ((AggregationResultSet)joinRS).getAggregationResultRows();
+ IDiskArray newRsRows = new BufferedStructureArray(AggregationResultRow.getCreator( ), aggregationResultRows.size( ));
+ int result;
+ for (int index = 0; index < joinRS.length( ); index++)
+ {
+ joinRS.seek( index );
+ result = Collections.binarySearch( detailMember, new Members( joinRS.getCurrentRow( ).getLevelMembers( ) ) );
+
+ if (result >= 0 )
+ {
+ newRsRows.add(aggregationResultRows.get( index ));
+ }
+ }
+ ((AggregationResultSet)joinRS).setAggregationResultRows( newRsRows );
+ detailMember.clear( );
+
+ }
+
+ private class Members implements Comparable<Members>
+ {
+
+ public Member[] members;
+ public Members(Member[] members)
+ {
+ this.members = members;
+ }
+
+ @Override
+ public int compareTo( Members other )
+ {
+ for (int i = 0; i < members.length; i++)
+ {
+ int result = members[i].compareTo( other.members[i] );
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+ return 0;
+ }
+
+ }
+
+ private List getNoAggrUpdateFilters( List filters )
+ {
+ List NoAggrUpdateFilters = new ArrayList( );
+
+ for ( int i = 0; i < filters.size( ); i++ )
+ {
+ if ( !( (IFilterDefinition) filters.get( i ) ).updateAggregation( ) )
+ NoAggrUpdateFilters.add( filters.get( i ) );
+ }
+ return NoAggrUpdateFilters;
+ }
private DrilledAggregationDefinition[] preparedDrillAggregation(
ICubeQueryDefinition cubeQueryDefinition,
@@ -478,7 +667,7 @@ public class QueryExecutor
private IAggregationResultSet[] populateRs( BirtCubeView view,
AggregationDefinition[] aggrDefns,
CubeQueryExecutorHelper cubeQueryExcutorHelper2,
- StopSign stopSign, boolean saveToRD ) throws IOException, BirtException
+ StopSign stopSign, boolean saveToRD, IBindingValueFetcher fetcher ) throws IOException, BirtException
{
IAggregationResultSet[] rs = null;
@@ -491,7 +680,7 @@ public class QueryExecutor
|| executor.getCubeQueryDefinition( ).cacheQueryResults( ) )
id = executor.getSession( ).getQueryResultIDUtil( ).nextID( );
- rs = executeQuery( view, aggrDefns, saveToRD, id );
+ rs = executeQuery( view, aggrDefns, saveToRD, id ,fetcher );
}
else
{
@@ -521,7 +710,7 @@ public class QueryExecutor
}
else
{
- rs = executeQuery( view, aggrDefns, saveToRD, id );
+ rs = executeQuery( view, aggrDefns, saveToRD, id ,fetcher );
}
}
}
@@ -532,12 +721,13 @@ public class QueryExecutor
private IAggregationResultSet[] executeQuery( BirtCubeView view,
AggregationDefinition[] aggrDefns, boolean saveToRD,
- String queryResutID ) throws IOException, BirtException
+ String queryResutID, IBindingValueFetcher fetcher ) throws IOException, BirtException
{
IAggregationResultSet[] rs;
CubeQueryExecutor executor = view.getCubeQueryExecutor( );
rs = cubeQueryExecutorHelper.execute( aggrDefns, executor.getSession( ).getStopSign( ) );
+ rs = applyNoAggrUpdateFilters( executor, rs, view.getCube( ) , fetcher );
//process mirror operation
MirrorOperationExecutor moe = new MirrorOperationExecutor( );
rs = moe.execute( rs, view, cubeQueryExecutorHelper );