| author | lzhang | 2011-12-13 23:18:37 (EST) |
|---|---|---|
| committer | xgu | 2011-12-13 23:21:26 (EST) |
| commit | 8fbe0b7c2e637f0ff4c402d5fe27932ca2c181df (patch) (side-by-side diff) | |
| tree | 5b490f7a7c0cec68826db5e739856beb18ea5771 | |
| parent | 67536f2cc5c5aa726768507fba6086ec485ee912 (diff) | |
| download | org.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
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 ); |

