Search in sources :

Example 1 with VisualTotalMember

use of mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember in project mondrian by pentaho.

the class RolapResult method processDistinctMeasureExpr.

/**
 * Distinct counts are aggregated separately from other measures. We need to apply filters to each level in the query.
 *
 * <p>
 * Replace VisualTotalMember expressions with new expressions where all leaf level members are included.
 * </p>
 *
 * <p>
 * Example. For MDX query:
 *
 * <blockquote>
 *
 * <pre>
 * WITH SET [XL_Row_Dim_0] AS
 *         VisualTotals(
 *           Distinct(
 *             Hierarchize(
 *               {Ascendants([Store].[All Stores].[USA].[CA]),
 *                Descendants([Store].[All Stores].[USA].[CA])})))
 *        select NON EMPTY
 *          Hierarchize(
 *            Intersect(
 *              {DrilldownLevel({[Store].[All Stores]})},
 *              [XL_Row_Dim_0])) ON COLUMNS
 *        from [HR]
 *        where [Measures].[Number of Employees]
 * </pre>
 *
 * </blockquote>
 *
 * <p>
 * For member [Store].[All Stores], we replace aggregate expression
 *
 * <blockquote>
 *
 * <pre>
 * Aggregate({[Store].[All Stores].[USA]})
 * </pre>
 *
 * </blockquote>
 * <p>
 * with
 *
 * <blockquote>
 *
 * <pre>
 * Aggregate({[Store].[All Stores].[USA].[CA].[Alameda].[HQ],
 *               [Store].[All Stores].[USA].[CA].[Beverly Hills].[Store 6],
 *               [Store].[All Stores].[USA].[CA].[Los Angeles].[Store 7],
 *               [Store].[All Stores].[USA].[CA].[San Diego].[Store 24],
 *               [Store].[All Stores].[USA].[CA].[San Francisco].[Store 14]
 *              })
 * </pre>
 *
 * </blockquote>
 *
 * <p>
 * TODO: Can be optimized. For that particular query we don't need to go to the lowest level. We can simply replace it
 * with:
 *
 * <pre>
 * Aggregate({[Store].[All Stores].[USA].[CA]})
 * </pre>
 *
 * Because all children of [Store].[All Stores].[USA].[CA] are included.
 * </p>
 */
private List<Member> processDistinctMeasureExpr(List<Member> tuple, RolapBaseCubeMeasure measure) {
    for (Member member : tuple) {
        if (!(member instanceof VisualTotalMember)) {
            continue;
        }
        evaluator.setContext(measure);
        List<Member> exprMembers = new ArrayList<Member>();
        processMemberExpr(member, exprMembers);
        ((VisualTotalMember) member).setExpression(evaluator, exprMembers);
    }
    return tuple;
}
Also used : VisualTotalMember(mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember) ArrayList(java.util.ArrayList) Member(mondrian.olap.Member) VisualTotalMember(mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember)

Example 2 with VisualTotalMember

use of mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember in project mondrian by pentaho.

the class RolapResult method processMemberExpr.

private static void processMemberExpr(Object o, List<Member> exprMembers) {
    if (o instanceof Member && o instanceof RolapCubeMember) {
        exprMembers.add((Member) o);
    } else if (o instanceof VisualTotalMember) {
        VisualTotalMember member = (VisualTotalMember) o;
        Exp exp = member.getExpression();
        processMemberExpr(exp, exprMembers);
    } else if (o instanceof Exp && !(o instanceof MemberExpr)) {
        Exp exp = (Exp) o;
        ResolvedFunCall funCall = (ResolvedFunCall) exp;
        Exp[] exps = funCall.getArgs();
        processMemberExpr(exps, exprMembers);
    } else if (o instanceof Exp[]) {
        Exp[] exps = (Exp[]) o;
        for (Exp exp : exps) {
            processMemberExpr(exp, exprMembers);
        }
    } else if (o instanceof MemberExpr) {
        MemberExpr memberExp = (MemberExpr) o;
        Member member = memberExp.getMember();
        processMemberExpr(member, exprMembers);
    }
}
Also used : MemberExpr(mondrian.mdx.MemberExpr) VisualTotalMember(mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember) ResolvedFunCall(mondrian.mdx.ResolvedFunCall) DummyExp(mondrian.calc.DummyExp) Exp(mondrian.olap.Exp) Member(mondrian.olap.Member) VisualTotalMember(mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember)

Example 3 with VisualTotalMember

use of mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember in project mondrian by pentaho.

the class RolapAggregationManager method makeCompoundGroup.

/**
 * Groups members (or tuples) from the same compound (i.e. hierarchy) into
 * groups that are constrained by the same set of columns.
 *
 * <p>E.g.
 *
 * <pre>Members
 *     [USA].[CA],
 *     [Canada].[BC],
 *     [USA].[CA].[San Francisco],
 *     [USA].[OR].[Portland]</pre>
 *
 * will be grouped into
 *
 * <pre>Group 1:
 *     {[USA].[CA], [Canada].[BC]}
 * Group 2:
 *     {[USA].[CA].[San Francisco], [USA].[OR].[Portland]}</pre>
 *
 * <p>This helps with generating optimal form of sql.
 *
 * <p>In case of aggregating over a list of tuples, similar logic also
 * applies.
 *
 * <p>For example:
 *
 * <pre>Tuples:
 *     ([Gender].[M], [Store].[USA].[CA])
 *     ([Gender].[F], [Store].[USA].[CA])
 *     ([Gender].[M], [Store].[USA])
 *     ([Gender].[F], [Store].[Canada])</pre>
 *
 * will be grouped into
 *
 * <pre>Group 1:
 *     {([Gender].[M], [Store].[USA].[CA]),
 *      ([Gender].[F], [Store].[USA].[CA])}
 * Group 2:
 *     {([Gender].[M], [Store].[USA]),
 *      ([Gender].[F], [Store].[Canada])}</pre>
 *
 * <p>This function returns a boolean value indicating if any constraint
 * can be created from the aggregationList. It is possible that only part
 * of the aggregationList can be applied, which still leads to a (partial)
 * constraint that is represented by the compoundGroupMap.
 */
private static boolean makeCompoundGroup(int starColumnCount, RolapCube baseCube, List<List<RolapMember>> aggregationList, Map<BitKey, List<RolapCubeMember[]>> compoundGroupMap) {
    // The more generalized aggregation as aggregating over tuples.
    // The special case is a tuple defined by only one member.
    int unsatisfiableTupleCount = 0;
    for (List<RolapMember> aggregation : aggregationList) {
        boolean isTuple;
        if (aggregation.size() > 0 && (aggregation.get(0) instanceof RolapCubeMember || aggregation.get(0) instanceof VisualTotalMember)) {
            isTuple = true;
        } else {
            ++unsatisfiableTupleCount;
            continue;
        }
        BitKey bitKey = BitKey.Factory.makeBitKey(starColumnCount);
        RolapCubeMember[] tuple;
        tuple = new RolapCubeMember[aggregation.size()];
        int i = 0;
        for (Member member : aggregation) {
            if (member instanceof VisualTotalMember) {
                tuple[i] = (RolapCubeMember) ((VisualTotalMember) member).getMember();
            } else {
                tuple[i] = (RolapCubeMember) member;
            }
            i++;
        }
        boolean tupleUnsatisfiable = false;
        for (RolapCubeMember member : tuple) {
            // Tuple cannot be constrained if any of the member cannot be.
            tupleUnsatisfiable = makeCompoundGroupForMember(member, baseCube, bitKey);
            if (tupleUnsatisfiable) {
                // If this tuple is unsatisfiable, skip it and try to
                // constrain the next tuple.
                unsatisfiableTupleCount++;
                break;
            }
        }
        if (!tupleUnsatisfiable && !bitKey.isEmpty()) {
            // Found tuple(columns) to constrain,
            // now add it to the compoundGroupMap
            addTupleToCompoundGroupMap(tuple, bitKey, compoundGroupMap);
        }
    }
    return (unsatisfiableTupleCount == aggregationList.size());
}
Also used : VisualTotalMember(mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember) VisualTotalMember(mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember)

Aggregations

VisualTotalMember (mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember)3 Member (mondrian.olap.Member)2 ArrayList (java.util.ArrayList)1 DummyExp (mondrian.calc.DummyExp)1 MemberExpr (mondrian.mdx.MemberExpr)1 ResolvedFunCall (mondrian.mdx.ResolvedFunCall)1 Exp (mondrian.olap.Exp)1