Skip to content

Commit

Permalink
Checkin: support step by step query execution for xTab
Browse files Browse the repository at this point in the history
  • Loading branch information
lzhang authored and xgu committed Dec 14, 2011
1 parent 67536f2 commit 8fbe0b7
Show file tree
Hide file tree
Showing 5 changed files with 558 additions and 15 deletions.
Expand Up @@ -644,4 +644,14 @@ public String getAggregationName( int index )
}
return null;
}

public IDiskArray getAggregationResultRows( )
{
return this.aggregationResultRows;
}

public void setAggregationResultRows( IDiskArray rows)
{
this.aggregationResultRows = rows;
}
}
Expand Up @@ -30,12 +30,16 @@
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;
Expand Down Expand Up @@ -403,6 +407,101 @@ private IDiskArray collectValidRowIndexArray(
}
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 )
{
Expand Down
Expand Up @@ -23,6 +23,7 @@
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;
Expand All @@ -31,8 +32,11 @@
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;
Expand Down Expand Up @@ -252,6 +256,242 @@ private void applyAggrFilter( IAggregationResultSet resultSet,
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
Expand Down

0 comments on commit 8fbe0b7

Please sign in to comment.