Search in sources :

Example 11 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.

the class DrilldownLevelTopBottomFunDef method compileCall.

public Calc compileCall(final ResolvedFunCall call, ExpCompiler compiler) {
    // Compile the member list expression. Ask for a mutable list, because
    // we're going to insert members into it later.
    final ListCalc listCalc = compiler.compileList(call.getArg(0), true);
    final IntegerCalc integerCalc = compiler.compileInteger(call.getArg(1));
    final LevelCalc levelCalc = call.getArgCount() > 2 && call.getArg(2).getCategory() != Category.Empty ? compiler.compileLevel(call.getArg(2)) : null;
    final Calc orderCalc = call.getArgCount() > 3 ? compiler.compileScalar(call.getArg(3), true) : new ValueCalc(new DummyExp(new ScalarType()));
    return new AbstractListCalc(call, new Calc[] { listCalc, integerCalc, orderCalc }) {

        public TupleList evaluateList(Evaluator evaluator) {
            // Use a native evaluator, if more efficient.
            // TODO: Figure this out at compile time.
            SchemaReader schemaReader = evaluator.getSchemaReader();
            NativeEvaluator nativeEvaluator = schemaReader.getNativeSetEvaluator(call.getFunDef(), call.getArgs(), evaluator, this);
            if (nativeEvaluator != null) {
                return (TupleList) nativeEvaluator.execute(ResultStyle.LIST);
            }
            TupleList list = listCalc.evaluateList(evaluator);
            int n = integerCalc.evaluateInteger(evaluator);
            if (n == FunUtil.IntegerNull || n <= 0) {
                return list;
            }
            Level level;
            if (levelCalc == null) {
                level = null;
            } else {
                level = levelCalc.evaluateLevel(evaluator);
            }
            List<Member> result = new ArrayList<Member>();
            assert list.getArity() == 1;
            for (Member member : list.slice(0)) {
                result.add(member);
                if (level != null && member.getLevel() != level) {
                    if (level.getDimension() != member.getDimension()) {
                        throw newEvalException(DrilldownLevelTopBottomFunDef.this, "Level '" + level.getUniqueName() + "' not compatible with member '" + member.getUniqueName() + "'");
                    }
                    continue;
                }
                List<Member> children = schemaReader.getMemberChildren(member);
                final int savepoint = evaluator.savepoint();
                List<Member> sortedChildren;
                try {
                    evaluator.setNonEmpty(false);
                    sortedChildren = Sorter.sortMembers(evaluator, children, children, orderCalc, top, true);
                } finally {
                    evaluator.restore(savepoint);
                }
                int x = Math.min(n, sortedChildren.size());
                for (int i = 0; i < x; i++) {
                    result.add(sortedChildren.get(i));
                }
            }
            return new UnaryTupleList(result);
        }

        public boolean dependsOn(Hierarchy hierarchy) {
            return anyDependsButFirst(getCalcs(), hierarchy);
        }
    };
}
Also used : ValueCalc(mondrian.calc.impl.ValueCalc) SchemaReader(mondrian.olap.SchemaReader) ScalarType(mondrian.olap.type.ScalarType) ArrayList(java.util.ArrayList) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) Calc(mondrian.calc.Calc) LevelCalc(mondrian.calc.LevelCalc) IntegerCalc(mondrian.calc.IntegerCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) ValueCalc(mondrian.calc.impl.ValueCalc) LevelCalc(mondrian.calc.LevelCalc) Evaluator(mondrian.olap.Evaluator) NativeEvaluator(mondrian.olap.NativeEvaluator) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) TupleList(mondrian.calc.TupleList) Hierarchy(mondrian.olap.Hierarchy) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) IntegerCalc(mondrian.calc.IntegerCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) DummyExp(mondrian.calc.DummyExp) Level(mondrian.olap.Level) Member(mondrian.olap.Member) NativeEvaluator(mondrian.olap.NativeEvaluator)

Example 12 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.

the class ExceptFunDef method compileCall.

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
    // todo: implement ALL
    final ListCalc listCalc0 = compiler.compileList(call.getArg(0));
    final ListCalc listCalc1 = compiler.compileList(call.getArg(1));
    return new AbstractListCalc(call, new Calc[] { listCalc0, listCalc1 }) {

        public TupleList evaluateList(Evaluator evaluator) {
            TupleList list0 = listCalc0.evaluateList(evaluator);
            if (list0.isEmpty()) {
                return list0;
            }
            TupleList list1 = listCalc1.evaluateList(evaluator);
            if (list1.isEmpty()) {
                return list0;
            }
            final Set<List<Member>> set1 = new HashSet<List<Member>>(list1);
            final TupleList result = new ArrayTupleList(list0.getArity(), list0.size());
            for (List<Member> tuple1 : list0) {
                if (!set1.contains(tuple1)) {
                    result.add(tuple1);
                }
            }
            return result;
        }
    };
}
Also used : ArrayTupleList(mondrian.calc.impl.ArrayTupleList) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ArrayTupleList(mondrian.calc.impl.ArrayTupleList) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ArrayTupleList(mondrian.calc.impl.ArrayTupleList)

Example 13 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.

the class ExistsFunDef method compileCall.

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
    final ListCalc listCalc1 = compiler.compileList(call.getArg(0));
    final ListCalc listCalc2 = compiler.compileList(call.getArg(1));
    return new AbstractListCalc(call, new Calc[] { listCalc1, listCalc2 }) {

        public TupleList evaluateList(Evaluator evaluator) {
            TupleList leftTuples = listCalc1.evaluateList(evaluator);
            if (leftTuples.isEmpty()) {
                return TupleCollections.emptyList(leftTuples.getArity());
            }
            TupleList rightTuples = listCalc2.evaluateList(evaluator);
            if (rightTuples.isEmpty()) {
                return TupleCollections.emptyList(leftTuples.getArity());
            }
            TupleList result = TupleCollections.createList(leftTuples.getArity());
            List<Hierarchy> leftDims = getHierarchies(leftTuples.get(0));
            List<Hierarchy> rightDims = getHierarchies(rightTuples.get(0));
            leftLoop: for (List<Member> leftTuple : leftTuples) {
                for (List<Member> rightTuple : rightTuples) {
                    if (existsInTuple(leftTuple, rightTuple, leftDims, rightDims, null)) {
                        result.add(leftTuple);
                        continue leftLoop;
                    }
                }
            }
            return result;
        }
    };
}
Also used : AbstractListCalc(mondrian.calc.impl.AbstractListCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) List(java.util.List) ArrayList(java.util.ArrayList)

Example 14 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.

the class HeadTailFunDef method compileCall.

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
    final ListCalc listCalc = compiler.compileList(call.getArg(0));
    final IntegerCalc integerCalc = call.getArgCount() > 1 ? compiler.compileInteger(call.getArg(1)) : ConstantCalc.constantInteger(1);
    if (head) {
        return new AbstractListCalc(call, new Calc[] { listCalc, integerCalc }) {

            public TupleList evaluateList(Evaluator evaluator) {
                final int savepoint = evaluator.savepoint();
                try {
                    evaluator.setNonEmpty(false);
                    TupleList list = listCalc.evaluateList(evaluator);
                    int count = integerCalc.evaluateInteger(evaluator);
                    return head(count, list);
                } finally {
                    evaluator.restore(savepoint);
                }
            }
        };
    } else {
        return new AbstractListCalc(call, new Calc[] { listCalc, integerCalc }) {

            public TupleList evaluateList(Evaluator evaluator) {
                final int savepoint = evaluator.savepoint();
                try {
                    evaluator.setNonEmpty(false);
                    TupleList list = listCalc.evaluateList(evaluator);
                    int count = integerCalc.evaluateInteger(evaluator);
                    return tail(count, list);
                } finally {
                    evaluator.restore(savepoint);
                }
            }
        };
    }
}
Also used : AbstractListCalc(mondrian.calc.impl.AbstractListCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) Evaluator(mondrian.olap.Evaluator)

Example 15 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.

the class DrilldownLevelFunDef method compileCall.

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
    final ListCalc listCalc = compiler.compileList(call.getArg(0));
    final LevelCalc levelCalc = call.getArgCount() > 1 && call.getArg(1).getType() instanceof mondrian.olap.type.LevelType ? compiler.compileLevel(call.getArg(1)) : null;
    final IntegerCalc indexCalc = call.getArgCount() > 2 ? compiler.compileInteger(call.getArg(2)) : null;
    final int arity = listCalc.getType().getArity();
    if (indexCalc == null) {
        return new AbstractListCalc(call, new Calc[] { listCalc, levelCalc }) {

            public TupleList evaluateList(Evaluator evaluator) {
                TupleList list = listCalc.evaluateList(evaluator);
                if (list.size() == 0) {
                    return list;
                }
                int searchDepth = -1;
                if (levelCalc != null) {
                    Level level = levelCalc.evaluateLevel(evaluator);
                    searchDepth = level.getDepth();
                }
                return new UnaryTupleList(drill(searchDepth, list.slice(0), evaluator));
            }
        };
    } else {
        return new AbstractListCalc(call, new Calc[] { listCalc, indexCalc }) {

            public TupleList evaluateList(Evaluator evaluator) {
                TupleList list = listCalc.evaluateList(evaluator);
                if (list.isEmpty()) {
                    return list;
                }
                final int index = indexCalc.evaluateInteger(evaluator);
                if (index < 0 || index >= arity) {
                    return list;
                }
                TupleList result = TupleCollections.createList(arity);
                final SchemaReader schemaReader = evaluator.getSchemaReader();
                final Member[] tupleClone = new Member[arity];
                for (List<Member> tuple : list) {
                    result.add(tuple);
                    final List<Member> children = schemaReader.getMemberChildren(tuple.get(index));
                    for (Member child : children) {
                        tuple.toArray(tupleClone);
                        tupleClone[index] = child;
                        result.addTuple(tupleClone);
                    }
                }
                return result;
            }
        };
    }
}
Also used : AbstractListCalc(mondrian.calc.impl.AbstractListCalc) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) mondrian.olap(mondrian.olap)

Aggregations

AbstractListCalc (mondrian.calc.impl.AbstractListCalc)21 Evaluator (mondrian.olap.Evaluator)9 TupleList (mondrian.calc.TupleList)7 UnaryTupleList (mondrian.calc.impl.UnaryTupleList)7 Hierarchy (mondrian.olap.Hierarchy)6 Member (mondrian.olap.Member)6 ArrayList (java.util.ArrayList)5 ListCalc (mondrian.calc.ListCalc)5 List (java.util.List)4 Calc (mondrian.calc.Calc)4 IntegerCalc (mondrian.calc.IntegerCalc)4 SchemaReader (mondrian.olap.SchemaReader)4 Type (mondrian.olap.type.Type)4 LevelCalc (mondrian.calc.LevelCalc)3 Level (mondrian.olap.Level)3 MemberCalc (mondrian.calc.MemberCalc)2 StringCalc (mondrian.calc.StringCalc)2 ValueCalc (mondrian.calc.impl.ValueCalc)2 ResolvedFunCall (mondrian.mdx.ResolvedFunCall)2 Exp (mondrian.olap.Exp)2