use of mondrian.rolap.sql.TupleConstraint in project mondrian by pentaho.
the class SqlTupleReader method chooseAggStar.
/**
* Obtains the AggStar instance which corresponds to an aggregate table which can be used to support the member
* constraint.
*
* @param constraint The tuple constraint to apply.
* @param evaluator the current evaluator to obtain the cube and members to be queried @return AggStar for aggregate
* table
* @param baseCube The base cube from which to choose an aggregation star. Can be null, in which case we use the
* evaluator's cube.
*/
AggStar chooseAggStar(TupleConstraint constraint, Evaluator evaluator, RolapCube baseCube) {
if (!MondrianProperties.instance().UseAggregates.get()) {
return null;
}
if (evaluator == null || !constraint.supportsAggTables()) {
return null;
}
if (baseCube == null) {
baseCube = (RolapCube) evaluator.getCube();
}
// Current cannot support aggregate tables for virtual cubes
if (baseCube.isVirtual()) {
return null;
}
RolapStar star = baseCube.getStar();
final int starColumnCount = star.getColumnCount();
BitKey measureBitKey = BitKey.Factory.makeBitKey(starColumnCount);
BitKey levelBitKey = BitKey.Factory.makeBitKey(starColumnCount);
// Convert global ordinal to cube based ordinal (the 0th dimension
// is always [Measures]). In the case of filter constraint this will
// be the measure on which the filter will be done.
// Since we support aggregated members as arguments, we'll expand
// this too.
// Failing to do so could result in chosing the wrong aggstar, as the
// level would not be passed to the bitkeys
final Member[] members = SqlConstraintUtils.expandSupportedCalculatedMembers(Arrays.asList(evaluator.getNonAllMembers()), evaluator).getMembersArray();
// if measure is calculated, we can't continue
if (!(members[0] instanceof RolapBaseCubeMeasure)) {
return null;
}
RolapBaseCubeMeasure measure = (RolapBaseCubeMeasure) members[0];
int bitPosition = ((RolapStar.Measure) measure.getStarMeasure()).getBitPosition();
// set a bit for each level which is constrained in the context
final CellRequest request = RolapAggregationManager.makeRequest(members);
if (request == null) {
// One or more calculated members. Cannot use agg table.
return null;
}
// TODO: RME why is this using the array of constrained columns
// from the CellRequest rather than just the constrained columns
// BitKey (method getConstrainedColumnsBitKey)?
RolapStar.Column[] columns = request.getConstrainedColumns();
for (RolapStar.Column column1 : columns) {
levelBitKey.set(column1.getBitPosition());
}
// set the masks
for (TargetBase target : targets) {
RolapLevel level = target.level;
if (!level.isAll()) {
RolapStar.Column column = ((RolapCubeLevel) level).getBaseStarKeyColumn(baseCube);
if (column != null) {
levelBitKey.set(column.getBitPosition());
}
}
}
// Set the bits for limited rollup members
RolapUtil.constraintBitkeyForLimitedMembers(evaluator, evaluator.getMembers(), baseCube, levelBitKey);
measureBitKey.set(bitPosition);
if (constraint instanceof RolapNativeCrossJoin.NonEmptyCrossJoinConstraint) {
// Cannot evaluate NonEmptyCrossJoinConstraint using an agg
// table if one of its args is a DescendantsConstraint.
RolapNativeCrossJoin.NonEmptyCrossJoinConstraint necj = (RolapNativeCrossJoin.NonEmptyCrossJoinConstraint) constraint;
for (CrossJoinArg arg : necj.args) {
if (arg instanceof DescendantsCrossJoinArg || arg instanceof MemberListCrossJoinArg) {
final RolapLevel level = arg.getLevel();
if (level != null && !level.isAll()) {
RolapStar.Column column = ((RolapCubeLevel) level).getBaseStarKeyColumn(baseCube);
if (column == null) {
// target group.
continue;
}
levelBitKey.set(column.getBitPosition());
}
}
}
} else if (constraint instanceof RolapNativeFilter.FilterConstraint) {
for (Member slicer : ((RolapEvaluator) evaluator).getSlicerMembers()) {
final Level level = slicer.getLevel();
if (level != null && !level.isAll()) {
final RolapStar.Column column = ((RolapCubeLevel) level).getBaseStarKeyColumn(baseCube);
levelBitKey.set(column.getBitPosition());
}
}
}
// find the aggstar using the masks
return AggregationManager.findAgg(star, levelBitKey, measureBitKey, new boolean[] { false });
}
Aggregations