Search in sources :

Example 6 with Cube

use of mondrian.olap.Cube in project mondrian by pentaho.

the class SegmentCacheTest method testSegmentCacheEvents.

public void testSegmentCacheEvents() throws Exception {
    SegmentCache mockCache = new MockSegmentCache();
    SegmentCacheWorker testWorker = new SegmentCacheWorker(mockCache, null);
    // Flush the cache before we start. Wait a second for the cache
    // flush to propagate.
    final CacheControl cc = getTestContext().getConnection().getCacheControl(null);
    Cube salesCube = getCube("Sales");
    cc.flush(cc.createMeasuresRegion(salesCube));
    Thread.sleep(1000);
    MondrianServer.forConnection(getTestContext().getConnection()).getAggregationManager().cacheMgr.segmentCacheWorkers.add(testWorker);
    final List<SegmentHeader> createdHeaders = new ArrayList<SegmentHeader>();
    final List<SegmentHeader> deletedHeaders = new ArrayList<SegmentHeader>();
    final SegmentCache.SegmentCacheListener listener = new SegmentCache.SegmentCacheListener() {

        public void handle(SegmentCacheEvent e) {
            switch(e.getEventType()) {
                case ENTRY_CREATED:
                    createdHeaders.add(e.getSource());
                    break;
                case ENTRY_DELETED:
                    deletedHeaders.add(e.getSource());
                    break;
                default:
                    throw new UnsupportedOperationException();
            }
        }
    };
    try {
        // Register our custom listener.
        ((CompositeSegmentCache) MondrianServer.forConnection(getTestContext().getConnection()).getAggregationManager().cacheMgr.compositeCache).addListener(listener);
        // Now execute a query and check the events
        executeQuery("select {[Measures].[Unit Sales]} on columns from [Sales]");
        // Wait for propagation.
        Thread.sleep(2000);
        assertEquals(2, createdHeaders.size());
        assertEquals(0, deletedHeaders.size());
        assertEquals("Sales", createdHeaders.get(0).cubeName);
        assertEquals("FoodMart", createdHeaders.get(0).schemaName);
        assertEquals("Unit Sales", createdHeaders.get(0).measureName);
        createdHeaders.clear();
        deletedHeaders.clear();
        // Now flush the segment and check the events.
        cc.flush(cc.createMeasuresRegion(salesCube));
        // Wait for propagation.
        Thread.sleep(2000);
        assertEquals(0, createdHeaders.size());
        assertEquals(2, deletedHeaders.size());
        assertEquals("Sales", deletedHeaders.get(0).cubeName);
        assertEquals("FoodMart", deletedHeaders.get(0).schemaName);
        assertEquals("Unit Sales", deletedHeaders.get(0).measureName);
    } finally {
        ((CompositeSegmentCache) MondrianServer.forConnection(getTestContext().getConnection()).getAggregationManager().cacheMgr.compositeCache).removeListener(listener);
        MondrianServer.forConnection(getTestContext().getConnection()).getAggregationManager().cacheMgr.segmentCacheWorkers.remove(testWorker);
    }
}
Also used : SegmentHeader(mondrian.spi.SegmentHeader) ArrayList(java.util.ArrayList) CompositeSegmentCache(mondrian.rolap.agg.SegmentCacheManager.CompositeSegmentCache) Cube(mondrian.olap.Cube) CompositeSegmentCache(mondrian.rolap.agg.SegmentCacheManager.CompositeSegmentCache) SegmentCache(mondrian.spi.SegmentCache) CacheControl(mondrian.olap.CacheControl)

Example 7 with Cube

use of mondrian.olap.Cube in project mondrian by pentaho.

the class BatchTestCase method getMeasure.

protected RolapStar.Measure getMeasure(String cube, String measureName) {
    final Connection connection = getFoodMartConnection();
    final boolean fail = true;
    Cube salesCube = connection.getSchema().lookupCube(cube, fail);
    Member measure = salesCube.getSchemaReader(null).getMemberByUniqueName(Util.parseIdentifier(measureName), fail);
    return RolapStar.getStarMeasure(measure);
}
Also used : Cube(mondrian.olap.Cube) Connection(mondrian.olap.Connection) Member(mondrian.olap.Member)

Example 8 with Cube

use of mondrian.olap.Cube in project mondrian by pentaho.

the class BatchTestCase method clearCache.

private void clearCache(RolapCube cube) {
    // Clear the cache for the Sales cube, so the query runs as if
    // for the first time. (TODO: Cleaner way to do this.)
    final Cube salesCube = getConnection().getSchema().lookupCube("Sales", true);
    RolapHierarchy hierarchy = (RolapHierarchy) salesCube.lookupHierarchy(new Id.NameSegment("Store", Id.Quoting.UNQUOTED), false);
    SmartMemberReader memberReader = (SmartMemberReader) hierarchy.getMemberReader();
    MemberCacheHelper cacheHelper = memberReader.cacheHelper;
    cacheHelper.mapLevelToMembers.cache.clear();
    cacheHelper.mapMemberToChildren.cache.clear();
    // Flush the cache, to ensure that the query gets executed.
    cube.clearCachedAggregations(true);
    CacheControl cacheControl = getConnection().getCacheControl(null);
    final CacheControl.CellRegion measuresRegion = cacheControl.createMeasuresRegion(cube);
    cacheControl.flush(measuresRegion);
    waitForFlush(cacheControl, measuresRegion, cube.getName());
}
Also used : Cube(mondrian.olap.Cube) CacheControl(mondrian.olap.CacheControl)

Example 9 with Cube

use of mondrian.olap.Cube in project pentaho-platform by pentaho.

the class MondrianModelComponent method getInitialQuery.

public static String getInitialQuery(final Connection connection, final String cubeName) throws Throwable {
    String measuresMdx = null;
    String columnsMdx = null;
    // $NON-NLS-1$
    String whereMdx = "";
    StringBuffer rowsMdx = new StringBuffer();
    // Get catalog info, if exists
    String catalog = connection.getCatalogName();
    MondrianCatalogComplementInfo catalogComplementInfo = MondrianCatalogHelper.getInstance().getCatalogComplementInfoMap(catalog);
    try {
        Schema schema = connection.getSchema();
        if (schema == null) {
            Logger.error("MondrianModelComponent", Messages.getInstance().getErrorString("MondrianModel.ERROR_0002_INVALID_SCHEMA", // $NON-NLS-1$ //$NON-NLS-2$
            connection.getConnectString()));
            return null;
        }
        Cube[] cubes = schema.getCubes();
        if ((cubes == null) || (cubes.length == 0)) {
            Logger.error("MondrianModelComponent", Messages.getInstance().getErrorString("MondrianModel.ERROR_0003_NO_CUBES", // $NON-NLS-1$ //$NON-NLS-2$
            connection.getConnectString()));
            return null;
        }
        if ((cubes.length > 1) && (cubeName == null)) {
            Logger.error("MondrianModelComponent", Messages.getInstance().getErrorString("MondrianModel.ERROR_0004_CUBE_NOT_SPECIFIED", // $NON-NLS-1$ //$NON-NLS-2$
            connection.getConnectString()));
            return null;
        }
        Cube cube = null;
        if (cubes.length == 1) {
            cube = cubes[0];
        } else {
            for (Cube element : cubes) {
                if (element.getName().equals(cubeName)) {
                    cube = element;
                    break;
                }
            }
        }
        if (cube == null) {
            Logger.error("MondrianModelComponent", Messages.getInstance().getErrorString("MondrianModel.ERROR_0005_CUBE_NOT_FOUND", cubeName, // $NON-NLS-1$ //$NON-NLS-2$
            connection.getConnectString()));
            return null;
        }
        // If we have any whereConditions block, we need to find which hierarchies they are in
        // and not include them in the rows
        HashSet<Hierarchy> whereHierarchies = new HashSet<Hierarchy>();
        if (catalogComplementInfo != null && catalogComplementInfo.getWhereCondition(cube.getName()) != null && !catalogComplementInfo.getWhereCondition(cube.getName()).equals("")) {
            // $NON-NLS-1$
            final String rawString = catalogComplementInfo.getWhereCondition(cube.getName());
            try {
                // According to Julian, the better way to resolve the names is to build a query
                final String queryStr = // $NON-NLS-1$ //$NON-NLS-2$
                "select " + rawString + " on columns, {} on rows from " + cube.getName();
                final Query query = connection.parseQuery(queryStr);
                final Hierarchy[] hierarchies = query.getMdxHierarchiesOnAxis(AxisOrdinal.StandardAxisOrdinal.COLUMNS);
                boolean isWhereValid = true;
                for (int i = 0; i < hierarchies.length && isWhereValid; i++) {
                    final Hierarchy hierarchy = hierarchies[i];
                    if (connection.getRole().canAccess(hierarchy)) {
                        whereHierarchies.add(hierarchy);
                    } else {
                        isWhereValid = false;
                        whereHierarchies.clear();
                    }
                }
                if (isWhereValid) {
                    // $NON-NLS-1$
                    whereMdx = " WHERE " + rawString;
                }
            } catch (Exception e) {
                // We found an error in the where slicer, so we'll just act like it wasn't here
                whereHierarchies.clear();
            }
        }
        Dimension[] dimensions = cube.getDimensions();
        if ((dimensions == null) || (dimensions.length == 0)) {
            Logger.error("MondrianModelComponent", Messages.getInstance().getErrorString("MondrianModel.ERROR_0006_NO_DIMENSIONS", cubeName, // $NON-NLS-1$ //$NON-NLS-2$
            connection.getConnectString()));
            return null;
        }
        for (Dimension element : dimensions) {
            final Hierarchy hierarchy = element.getHierarchy();
            if (hierarchy == null) {
                Logger.error("MondrianModelComponent", Messages.getInstance().getErrorString("MondrianModel.ERROR_0007_NO_HIERARCHIES", element.getName(), cubeName, // $NON-NLS-1$ //$NON-NLS-2$
                connection.getConnectString()));
                return null;
            }
            if (!connection.getRole().canAccess(hierarchy)) {
                // We can't access this element
                continue;
            }
            if (whereHierarchies.contains(hierarchy)) {
                // We have it on the where condition - skip it
                continue;
            }
            Member member = Locus.execute((RolapConnection) connection, "Retrieving default members in plugin", new Locus.Action<Member>() {

                public Member execute() {
                    return connection.getSchemaReader().getHierarchyDefaultMember(hierarchy);
                }
            });
            if (member == null) {
                Logger.error("MondrianModelComponent", Messages.getInstance().getErrorString("MondrianModel.ERROR_0008_NO_DEFAULT_MEMBER", element.getName(), cubeName, // $NON-NLS-1$ //$NON-NLS-2$
                connection.getConnectString()));
                return null;
            }
            if (element.isMeasures()) {
                // measuresMdx = "with member "+ member.getUniqueName();
                // //$NON-NLS-1$
                // $NON-NLS-1$
                measuresMdx = "";
                // $NON-NLS-1$ //$NON-NLS-2$
                columnsMdx = " select NON EMPTY {" + member.getUniqueName() + "} ON columns, ";
            } else {
                if (rowsMdx.length() > 0) {
                    // $NON-NLS-1$
                    rowsMdx.append(", ");
                }
                rowsMdx.append(member.getUniqueName());
            }
        }
        if ((measuresMdx != null) && (columnsMdx != null) && (rowsMdx.length() > 0)) {
            StringBuffer result = new StringBuffer(measuresMdx.length() + columnsMdx.length() + rowsMdx.length() + 50);
            // $NON-NLS-1$
            result.append(measuresMdx).append(columnsMdx).append("NON EMPTY {(").append(rowsMdx).append(// $NON-NLS-1$
            ")} ON rows ").append(// $NON-NLS-1$ //$NON-NLS-2$
            "from [" + cube.getName() + "]").append(whereMdx);
            return result.toString();
        }
        return null;
    } catch (Throwable t) {
        if (t instanceof MondrianException) {
            // pull the cause out, otherwise it never gets logged
            Throwable cause = ((MondrianException) t).getCause();
            if (cause != null) {
                throw cause;
            } else {
                throw t;
            }
        } else {
            throw t;
        }
    }
}
Also used : Query(mondrian.olap.Query) Schema(mondrian.olap.Schema) Dimension(mondrian.olap.Dimension) MondrianException(mondrian.olap.MondrianException) Hierarchy(mondrian.olap.Hierarchy) Cube(mondrian.olap.Cube) MondrianCatalogComplementInfo(org.pentaho.platform.plugin.action.mondrian.catalog.MondrianCatalogComplementInfo) Locus(mondrian.server.Locus) MondrianException(mondrian.olap.MondrianException) Member(mondrian.olap.Member) HashSet(java.util.HashSet)

Example 10 with Cube

use of mondrian.olap.Cube in project mdx-kylin by Kyligence.

the class BuiltinFunTable method defineFunctions.

public void defineFunctions(Builder builder) {
    builder.defineReserved("NULL");
    // Empty expression
    builder.define(new FunDefBase("", "", "Dummy function representing the empty expression", Syntax.Empty, Category.Empty, new int[0]) {
    });
    // "SetToArray(<Set>[, <Set>]...[, <Numeric Expression>])"
    if (false)
        builder.define(new FunDefBase("SetToArray", "SetToArray(<Set>[, <Set>]...[, <Numeric Expression>])", "Converts one or more sets to an array for use in a user-defined function.", "fa*") {

            public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
                throw new UnsupportedOperationException();
            }
        });
    // PROPERTY FUNCTIONS
    // <Dimension>.<Property>
    DimensionPropertyFunDef.define(builder);
    // <Hierarchy>.<Property>
    HierarchyPropertyFunDef.define(builder);
    // <Level>.<Property>
    LevelPropertyFunDef.define(builder);
    // <Member>.<Property>
    MemberPropertyFunDef.define(builder);
    // 
    // DIMENSION FUNCTIONS
    builder.define(HierarchyDimensionFunDef.instance);
    // "<Dimension>.Dimension"
    builder.define(DimensionDimensionFunDef.INSTANCE);
    // "<Level>.Dimension"
    builder.define(LevelDimensionFunDef.INSTANCE);
    // "<Member>.Dimension"
    builder.define(MemberDimensionFunDef.INSTANCE);
    // "Dimensions(<Numeric Expression>)"
    builder.define(DimensionsNumericFunDef.INSTANCE);
    // "Dimensions(<String Expression>)"
    builder.define(DimensionsStringFunDef.INSTANCE);
    // 
    // HIERARCHY FUNCTIONS
    builder.define(LevelHierarchyFunDef.instance);
    builder.define(MemberHierarchyFunDef.instance);
    // 
    // LEVEL FUNCTIONS
    builder.define(MemberLevelFunDef.instance);
    // "<Hierarchy>.Levels(<Numeric Expression>)"
    builder.define(new FunDefBase("Levels", "Returns the level whose position in a hierarchy is specified by a numeric expression.", "mlhn") {

        public Type getResultType(Validator validator, Exp[] args) {
            final Type argType = args[0].getType();
            return LevelType.forType(argType);
        }

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final HierarchyCalc hierarchyCalc = compiler.compileHierarchy(call.getArg(0));
            final IntegerCalc ordinalCalc = compiler.compileInteger(call.getArg(1));
            return new AbstractLevelCalc(call, new Calc[] { hierarchyCalc, ordinalCalc }) {

                public Level evaluateLevel(Evaluator evaluator) {
                    Hierarchy hierarchy = hierarchyCalc.evaluateHierarchy(evaluator);
                    int ordinal = ordinalCalc.evaluateInteger(evaluator);
                    return nthLevel(hierarchy, ordinal);
                }
            };
        }

        Level nthLevel(Hierarchy hierarchy, int n) {
            if (n >= hierarchy.getLevelList().size() || n < 0) {
                throw newEvalException(this, "Index '" + n + "' out of bounds");
            }
            return hierarchy.getLevelList().get(n);
        }
    });
    // "<Hierarchy>.Levels(<String Expression>)"
    builder.define(new FunDefBase("Levels", "Returns the level whose name is specified by a string expression.", "mlhS") {

        public Type getResultType(Validator validator, Exp[] args) {
            final Type argType = args[0].getType();
            return LevelType.forType(argType);
        }

        public Calc compileCall(final ResolvedFunCall call, ExpCompiler compiler) {
            final HierarchyCalc hierarchyCalc = compiler.compileHierarchy(call.getArg(0));
            final StringCalc nameCalc = compiler.compileString(call.getArg(1));
            return new AbstractLevelCalc(call, new Calc[] { hierarchyCalc, nameCalc }) {

                public Level evaluateLevel(Evaluator evaluator) {
                    Hierarchy hierarchy = hierarchyCalc.evaluateHierarchy(evaluator);
                    String name = nameCalc.evaluateString(evaluator);
                    for (Level level : hierarchy.getLevelList()) {
                        if (level.getName().equals(name)) {
                            return level;
                        }
                    }
                    throw newEvalException(call.getFunDef(), "Level '" + name + "' not found in hierarchy '" + hierarchy + "'");
                }
            };
        }
    });
    // "Levels(<String Expression>)"
    builder.define(new FunDefBase("Levels", "Returns the level whose name is specified by a string expression.", "flS") {

        public Type getResultType(Validator validator, Exp[] args) {
            final Type argType = args[0].getType();
            return LevelType.forType(argType);
        }

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final StringCalc stringCalc = compiler.compileString(call.getArg(0));
            return new AbstractLevelCalc(call, new Calc[] { stringCalc }) {

                public Level evaluateLevel(Evaluator evaluator) {
                    String levelName = stringCalc.evaluateString(evaluator);
                    return findLevel(evaluator, levelName);
                }
            };
        }

        Level findLevel(Evaluator evaluator, String s) {
            Cube cube = evaluator.getCube();
            OlapElement o = (s.startsWith("[")) ? evaluator.getSchemaReader().lookupCompound(cube, parseIdentifier(s), false, Category.Level) : // brackets, so don't even try
            null;
            if (o instanceof Level) {
                return (Level) o;
            } else if (o == null) {
                throw newEvalException(this, "Level '" + s + "' not found");
            } else {
                throw newEvalException(this, "Levels('" + s + "') found " + o);
            }
        }
    });
    // 
    // LOGICAL FUNCTIONS
    builder.define(IsEmptyFunDef.FunctionResolver);
    builder.define(IsEmptyFunDef.PostfixResolver);
    builder.define(IsNullFunDef.Resolver);
    IsFunDef.define(builder);
    builder.define(AsFunDef.RESOLVER);
    // 
    // MEMBER FUNCTIONS
    builder.define(AncestorFunDef.Resolver);
    builder.define(new FunDefBase("Cousin", "<Member> Cousin(<Member>, <Ancestor Member>)", "Returns the member with the same relative position under <ancestor member> as the member specified.", "fmmm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            final MemberCalc ancestorMemberCalc = compiler.compileMember(call.getArg(1));
            return new AbstractMemberCalc(call, new Calc[] { memberCalc, ancestorMemberCalc }) {

                public Member evaluateMember(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    Member ancestorMember = ancestorMemberCalc.evaluateMember(evaluator);
                    return cousin(evaluator.getSchemaReader(), member, ancestorMember);
                }
            };
        }
    });
    builder.define(HierarchyCurrentMemberFunDef.instance);
    builder.define(NamedSetCurrentFunDef.instance);
    builder.define(NamedSetCurrentOrdinalFunDef.instance);
    // "<Dimension>.DefaultMember". The function is implemented using an
    // implicit cast to hierarchy, and we create a FunInfo for
    // documentation & backwards compatibility.
    builder.define(new FunInfo("DefaultMember", "Returns the default member of a dimension.", "pmd"));
    // "<Hierarchy>.DefaultMember"
    builder.define(new FunDefBase("DefaultMember", "Returns the default member of a hierarchy.", "pmh") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final HierarchyCalc hierarchyCalc = compiler.compileHierarchy(call.getArg(0));
            return new AbstractMemberCalc(call, new Calc[] { hierarchyCalc }) {

                public Member evaluateMember(Evaluator evaluator) {
                    Hierarchy hierarchy = hierarchyCalc.evaluateHierarchy(evaluator);
                    return evaluator.getSchemaReader().getHierarchyDefaultMember(hierarchy);
                }
            };
        }
    });
    // "<Member>.FirstChild"
    builder.define(new FunDefBase("FirstChild", "Returns the first child of a member.", "pmm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractMemberCalc(call, new Calc[] { memberCalc }) {

                public Member evaluateMember(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    assert member instanceof RolapMember;
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled()) {
                        HierarchyMemberTree memberTree = null;
                        try {
                            memberTree = hierarchyCache.getMemberTree(((RolapMember) member).getHierarchy());
                        } catch (ExecutionException | SQLException e) {
                            throw new MondrianException(e);
                        }
                        return memberTree.getFirstChildMember(member.getUniqueName());
                    } else {
                        return firstChild(evaluator, member);
                    }
                }
            };
        }

        Member firstChild(Evaluator evaluator, Member member) {
            List<Member> children = evaluator.getSchemaReader().getMemberChildren(member);
            return (children.size() == 0) ? member.getHierarchy().getNullMember() : children.get(0);
        }
    });
    // <Member>.FirstSibling
    builder.define(new FunDefBase("FirstSibling", "Returns the first child of the parent of a member.", "pmm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractMemberCalc(call, new Calc[] { memberCalc }) {

                public Member evaluateMember(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    assert member instanceof RolapMember;
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled()) {
                        HierarchyMemberTree memberTree = null;
                        try {
                            memberTree = hierarchyCache.getMemberTree(((RolapMember) member).getHierarchy());
                        } catch (ExecutionException | SQLException e) {
                            throw new MondrianException(e);
                        }
                        return memberTree.getFirstSiblingMember(member.getUniqueName());
                    } else {
                        return firstSibling(member, evaluator);
                    }
                }
            };
        }

        Member firstSibling(Member member, Evaluator evaluator) {
            Member parent = member.getParentMember();
            List<Member> children;
            final SchemaReader schemaReader = evaluator.getSchemaReader();
            if (parent == null) {
                if (member.isNull()) {
                    return member;
                }
                children = schemaReader.getHierarchyRootMembers(member.getHierarchy());
            } else {
                children = schemaReader.getMemberChildren(parent);
            }
            return children.get(0);
        }
    });
    builder.define(LeadLagFunDef.LagResolver);
    // <Member>.LastChild
    builder.define(new FunDefBase("LastChild", "Returns the last child of a member.", "pmm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractMemberCalc(call, new Calc[] { memberCalc }) {

                public Member evaluateMember(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    assert member instanceof RolapMember;
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled()) {
                        HierarchyMemberTree memberTree = null;
                        try {
                            memberTree = hierarchyCache.getMemberTree(((RolapMember) member).getHierarchy());
                        } catch (ExecutionException | SQLException e) {
                            throw new MondrianException(e);
                        }
                        return memberTree.getLastChildMember(member.getUniqueName());
                    } else {
                        return lastChild(evaluator, member);
                    }
                }
            };
        }

        Member lastChild(Evaluator evaluator, Member member) {
            List<Member> children = evaluator.getSchemaReader().getMemberChildren(member);
            return (children.size() == 0) ? member.getHierarchy().getNullMember() : children.get(children.size() - 1);
        }
    });
    // <Member>.LastSibling
    builder.define(new FunDefBase("LastSibling", "Returns the last child of the parent of a member.", "pmm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractMemberCalc(call, new Calc[] { memberCalc }) {

                public Member evaluateMember(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    assert member instanceof RolapMember;
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled()) {
                        HierarchyMemberTree memberTree = null;
                        try {
                            memberTree = hierarchyCache.getMemberTree(((RolapMember) member).getHierarchy());
                        } catch (ExecutionException | SQLException e) {
                            throw new MondrianException(e);
                        }
                        return memberTree.getLastSiblingMember(member.getUniqueName());
                    } else {
                        return firstSibling(member, evaluator);
                    }
                }
            };
        }

        Member firstSibling(Member member, Evaluator evaluator) {
            Member parent = member.getParentMember();
            List<Member> children;
            final SchemaReader schemaReader = evaluator.getSchemaReader();
            if (parent == null) {
                if (member.isNull()) {
                    return member;
                }
                children = schemaReader.getHierarchyRootMembers(member.getHierarchy());
            } else {
                children = schemaReader.getMemberChildren(parent);
            }
            return children.get(children.size() - 1);
        }
    });
    builder.define(LeadLagFunDef.LeadResolver);
    // Members(<String Expression>)
    builder.define(new FunDefBase("Members", "Returns the member whose name is specified by a string expression.", "fmS") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final StringCalc memberNameCalc = compiler.compileString(call.getArg(0));
            return new AbstractMemberCalc(call, new Calc[] { memberNameCalc }) {

                @Override
                public Member evaluateMember(Evaluator evaluator) {
                    String memberName = memberNameCalc.evaluateString(evaluator);
                    if (memberName == null) {
                        throw newEvalException(MondrianResource.instance().NullValue.ex());
                    }
                    return parseMember(evaluator, memberName, null);
                }
            };
        }
    });
    // <Member>.NextMember
    builder.define(new FunDefBase("NextMember", "Returns the next member in the level that contains a specified member.", "pmm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractMemberCalc(call, new Calc[] { memberCalc }) {

                public Member evaluateMember(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    assert member instanceof RolapMember;
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled()) {
                        HierarchyMemberTree memberTree = null;
                        try {
                            memberTree = hierarchyCache.getMemberTree(((RolapMember) member).getHierarchy());
                        } catch (ExecutionException | SQLException e) {
                            throw new MondrianException(e);
                        }
                        return memberTree.getNextMember(member.getUniqueName());
                    } else {
                        return evaluator.getSchemaReader().getLeadMember(member, 1);
                    }
                }
            };
        }
    });
    builder.define(OpeningClosingPeriodFunDef.OpeningPeriodResolver);
    builder.define(OpeningClosingPeriodFunDef.ClosingPeriodResolver);
    builder.define(MemberOrderKeyFunDef.instance);
    builder.define(ParallelPeriodFunDef.Resolver);
    // <Member>.Parent
    builder.define(new FunDefBase("Parent", "Returns the parent of a member.", "pmm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractMemberCalc(call, new Calc[] { memberCalc }) {

                public Member evaluateMember(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    return memberParent(evaluator, member);
                }
            };
        }

        Member memberParent(Evaluator evaluator, Member member) {
            Member parent = evaluator.getSchemaReader().getMemberParent(member);
            if (parent == null) {
                parent = member.getHierarchy().getNullMember();
            }
            return parent;
        }
    });
    // <Member>.PrevMember
    builder.define(new FunDefBase("PrevMember", "Returns the previous member in the level that contains a specified member.", "pmm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractMemberCalc(call, new Calc[] { memberCalc }) {

                public Member evaluateMember(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    assert member instanceof RolapMember;
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled()) {
                        HierarchyMemberTree memberTree = null;
                        try {
                            memberTree = hierarchyCache.getMemberTree(((RolapMember) member).getHierarchy());
                        } catch (ExecutionException | SQLException e) {
                            throw new MondrianException(e);
                        }
                        return memberTree.getPrevMember(member.getUniqueName());
                    } else {
                        return evaluator.getSchemaReader().getLeadMember(member, -1);
                    }
                }
            };
        }
    });
    builder.define(StrToMemberFunDef.INSTANCE);
    builder.define(ValidMeasureFunDef.instance);
    // 
    // NUMERIC FUNCTIONS
    builder.define(AggregateFunDef.resolver);
    // Obsolete??
    builder.define(new MultiResolver("$AggregateChildren", "$AggregateChildren(<Hierarchy>)", "Equivalent to 'Aggregate(<Hierarchy>.CurrentMember.Children); for internal use.", new String[] { "Inh" }) {

        protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) {
            return new FunDefBase(dummyFunDef) {

                public void unparse(Exp[] args, PrintWriter pw) {
                    pw.print(getName());
                    pw.print("(");
                    args[0].unparse(pw);
                    pw.print(")");
                }

                public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
                    final HierarchyCalc hierarchyCalc = compiler.compileHierarchy(call.getArg(0));
                    final Calc valueCalc = new ValueCalc(call);
                    return new GenericCalc(call) {

                        public Object evaluate(Evaluator evaluator) {
                            Hierarchy hierarchy = hierarchyCalc.evaluateHierarchy(evaluator);
                            return aggregateChildren(evaluator, hierarchy, valueCalc);
                        }

                        public Calc[] getCalcs() {
                            return new Calc[] { hierarchyCalc, valueCalc };
                        }
                    };
                }

                Object aggregateChildren(Evaluator evaluator, Hierarchy hierarchy, final Calc valueFunCall) {
                    Member member = evaluator.getPreviousContext(hierarchy);
                    List<Member> members = new ArrayList<Member>();
                    evaluator.getSchemaReader().getParentChildContributingChildren(member.getDataMember(), hierarchy, members);
                    Aggregator aggregator = (Aggregator) evaluator.getProperty(Property.AGGREGATION_TYPE, null);
                    if (aggregator == null) {
                        throw FunUtil.newEvalException(null, "Could not find an aggregator in the current " + "evaluation context");
                    }
                    Aggregator rollup = aggregator.getRollup();
                    if (rollup == null) {
                        throw FunUtil.newEvalException(null, "Don't know how to rollup aggregator '" + aggregator + "'");
                    }
                    final int savepoint = evaluator.savepoint();
                    try {
                        final Object o = rollup.aggregate(evaluator, new UnaryTupleList(members), valueFunCall);
                        return o;
                    } finally {
                        evaluator.restore(savepoint);
                    }
                }
            };
        }
    });
    builder.define(AvgFunDef.Resolver);
    builder.define(CorrelationFunDef.Resolver);
    builder.define(CountFunDef.Resolver);
    // <Set>.Count
    builder.define(new FunDefBase("Count", "Returns the number of tuples in a set including empty cells.", "pnx") {

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

                public int evaluateInteger(Evaluator evaluator) {
                    TupleList list = listCalc.evaluateList(evaluator);
                    return count(evaluator, list, true);
                }
            };
        }
    });
    builder.define(CovarianceFunDef.CovarianceResolver);
    builder.define(CovarianceFunDef.CovarianceNResolver);
    builder.define(IifFunDef.STRING_INSTANCE);
    builder.define(IifFunDef.NUMERIC_INSTANCE);
    builder.define(IifFunDef.TUPLE_INSTANCE);
    builder.define(IifFunDef.BOOLEAN_INSTANCE);
    builder.define(IifFunDef.MEMBER_INSTANCE);
    builder.define(IifFunDef.LEVEL_INSTANCE);
    builder.define(IifFunDef.HIERARCHY_INSTANCE);
    builder.define(IifFunDef.DIMENSION_INSTANCE);
    builder.define(IifFunDef.SET_INSTANCE);
    builder.define(LinReg.InterceptResolver);
    builder.define(LinReg.PointResolver);
    builder.define(LinReg.R2Resolver);
    builder.define(LinReg.SlopeResolver);
    builder.define(LinReg.VarianceResolver);
    builder.define(MinMaxFunDef.MaxResolver);
    builder.define(MinMaxFunDef.MinResolver);
    builder.define(MedianFunDef.Resolver);
    builder.define(PercentileFunDef.Resolver);
    // <Level>.Ordinal
    builder.define(new FunDefBase("Ordinal", "Returns the zero-based ordinal value associated with a level.", "pnl") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final LevelCalc levelCalc = compiler.compileLevel(call.getArg(0));
            return new AbstractIntegerCalc(call, new Calc[] { levelCalc }) {

                public int evaluateInteger(Evaluator evaluator) {
                    final Level level = levelCalc.evaluateLevel(evaluator);
                    return level.getDepth();
                }
            };
        }
    });
    builder.define(RankFunDef.Resolver);
    builder.define(CacheFunDef.Resolver);
    builder.define(GroupFunDef.Resolver);
    builder.define(PatternOrFunDef.Resolver);
    builder.define(PatternNamedSetExpFunDef.RESOLVER);
    builder.define(PatternDynamicArgCountFunDef.RESOLVER);
    builder.define(StdevFunDef.StdevResolver);
    builder.define(StdevFunDef.StddevResolver);
    builder.define(StdevPFunDef.StdevpResolver);
    builder.define(StdevPFunDef.StddevpResolver);
    builder.define(SumFunDef.Resolver);
    // <Measure>.Value
    builder.define(new FunDefBase("Value", "Returns the value of a measure.", "pnm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new GenericCalc(call) {

                public Object evaluate(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    final int savepoint = evaluator.savepoint();
                    evaluator.setContext(member);
                    try {
                        Object value = evaluator.evaluateCurrent();
                        return value;
                    } finally {
                        evaluator.restore(savepoint);
                    }
                }

                public boolean dependsOn(Hierarchy hierarchy) {
                    if (super.dependsOn(hierarchy)) {
                        return true;
                    }
                    if (memberCalc.getType().usesHierarchy(hierarchy, true)) {
                        return false;
                    }
                    return true;
                }

                public Calc[] getCalcs() {
                    return new Calc[] { memberCalc };
                }
            };
        }
    });
    builder.define(VarFunDef.VarResolver);
    builder.define(VarFunDef.VarianceResolver);
    builder.define(VarPFunDef.VariancePResolver);
    builder.define(VarPFunDef.VarPResolver);
    // 
    // SET FUNCTIONS
    builder.define(AddCalculatedMembersFunDef.resolver);
    // Ascendants(<Member>)
    builder.define(new FunDefBase("Ascendants", "Returns the set of the ascendants of a specified member.", "fxm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractListCalc(call, new Calc[] { memberCalc }) {

                public TupleList evaluateList(Evaluator evaluator) {
                    Member member = memberCalc.evaluateMember(evaluator);
                    return new UnaryTupleList(ascendants(evaluator.getSchemaReader(), member));
                }
            };
        }

        List<Member> ascendants(SchemaReader schemaReader, Member member) {
            if (member.isNull()) {
                return Collections.emptyList();
            }
            final List<Member> result = new ArrayList<Member>();
            result.add(member);
            schemaReader.getMemberAncestors(member, result);
            return result;
        }
    });
    builder.define(TopBottomCountFunDef.BottomCountResolver);
    builder.define(TopBottomPercentSumFunDef.BottomPercentResolver);
    builder.define(TopBottomPercentSumFunDef.BottomSumResolver);
    builder.define(TopBottomCountFunDef.TopCountResolver);
    builder.define(TopBottomPercentSumFunDef.TopPercentResolver);
    builder.define(TopBottomPercentSumFunDef.TopSumResolver);
    // <Member>.Children
    builder.define(new FunDefBase("Children", "Returns the children of a member.", "pxm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractListCalc(call, new Calc[] { memberCalc }, false) {

                public TupleList evaluateList(Evaluator evaluator) {
                    // Return the list of children. The list is immutable,
                    // hence 'false' above.
                    Member member = memberCalc.evaluateMember(evaluator);
                    assert member instanceof RolapMember;
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (!hierarchyCache.isCacheEnabled() || XmlaRequestContext.getContext().filterRowLimitFlag && MondrianProperties.instance().FilterRowLimit.get() > 0) {
                        return new UnaryTupleList(getNonEmptyMemberChildren(evaluator, member));
                    }
                    List<Member> children;
                    try {
                        children = new ArrayList<>(hierarchyCache.getMemberTree(((RolapMember) member).getHierarchy()).getChildrenMembers(member.getUniqueName()));
                    } catch (ExecutionException | SQLException e) {
                        throw new MondrianException(e);
                    }
                    return new UnaryTupleList(children);
                }
            };
        }
    });
    builder.define(CrossJoinFunDef.Resolver);
    builder.define(NonEmptyCrossJoinFunDef.nonEmptyResolver);
    builder.define(NonEmptyCrossJoinFunDef.nonEmptyCrossJoinResolver);
    builder.define(CrossJoinFunDef.StarResolver);
    builder.define(DescendantsFunDef.Resolver);
    builder.define(DescendantsFunDef.Resolver2);
    builder.define(DistinctFunDef.instance);
    builder.define(DrilldownLevelFunDef.Resolver);
    builder.define(DrilldownLevelTopBottomFunDef.DrilldownLevelTopResolver);
    builder.define(DrilldownLevelTopBottomFunDef.DrilldownLevelBottomResolver);
    builder.define(DrilldownMemberFunDef.Resolver);
    if (false)
        builder.define(new FunDefBase("DrilldownMemberBottom", "DrilldownMemberBottom(<Set1>, <Set2>, <Count>[, [<Numeric Expression>][, RECURSIVE]])", "Like DrilldownMember except that it includes only the bottom N children.", "fx*") {

            public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
                throw new UnsupportedOperationException();
            }
        });
    if (false)
        builder.define(new FunDefBase("DrilldownMemberTop", "DrilldownMemberTop(<Set1>, <Set2>, <Count>[, [<Numeric Expression>][, RECURSIVE]])", "Like DrilldownMember except that it includes only the top N children.", "fx*") {

            public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
                throw new UnsupportedOperationException();
            }
        });
    if (false)
        builder.define(new FunDefBase("DrillupLevel", "DrillupLevel(<Set>[, <Level>])", "Drills up the members of a set that are below a specified level.", "fx*") {

            public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
                throw new UnsupportedOperationException();
            }
        });
    if (false)
        builder.define(new FunDefBase("DrillupMember", "DrillupMember(<Set1>, <Set2>)", "Drills up the members in a set that are present in a second specified set.", "fx*") {

            public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
                throw new UnsupportedOperationException();
            }
        });
    builder.define(ExceptFunDef.exceptResolver);
    builder.define(ExceptFunDef.minusResolver);
    // <Measure> - <Measure> / <Numeric> - <Numeric> / <Tuple> - <Tuple>
    builder.define(InfixMinusNumericFunDef.numericMinusResolver);
    // <Measure> + <Measure> / <Numeric> + <Numeric> / <Tuple> + <Tuple>
    builder.define(InfixPlusNumericFunDef.numericPlusResolver);
    builder.define(ExistsFunDef.resolver);
    builder.define(ExtractFunDef.Resolver);
    builder.define(FilterFunDef.instance);
    builder.define(GenerateFunDef.ListResolver);
    builder.define(GenerateFunDef.StringResolver);
    builder.define(GenerateFunDef.IntegerResolver);
    builder.define(HeadTailFunDef.HeadResolver);
    builder.define(HierarchizeFunDef.Resolver);
    builder.define(IntersectFunDef.resolver);
    builder.define(LastPeriodsFunDef.Resolver);
    // <Dimension>.Members is really just shorthand for <Hierarchy>.Members
    builder.define(new FunInfo("Members", "Returns the set of members in a dimension.", "pxd"));
    // <Hierarchy>.Members
    builder.define(new FunDefBase("Members", "Returns the set of members in a hierarchy.", "pxh") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final HierarchyCalc hierarchyCalc = compiler.compileHierarchy(call.getArg(0));
            return new AbstractListCalc(call, new Calc[] { hierarchyCalc }) {

                public TupleList evaluateList(Evaluator evaluator) {
                    Hierarchy hierarchy = hierarchyCalc.evaluateHierarchy(evaluator);
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled()) {
                        assert hierarchy instanceof RolapCubeHierarchy;
                        List<Member> memberList = FunUtil.getHierarchyAllMembers(hierarchy);
                        return new UnaryTupleList(memberList);
                    } else {
                        return hierarchyMembers(hierarchy, evaluator, false);
                    }
                }
            };
        }
    });
    // <Hierarchy>.AllMembers
    builder.define(new FunDefBase("AllMembers", "Returns a set that contains all members, including calculated members, of the specified hierarchy.", "pxh") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final HierarchyCalc hierarchyCalc = compiler.compileHierarchy(call.getArg(0));
            return new AbstractListCalc(call, new Calc[] { hierarchyCalc }) {

                public TupleList evaluateList(Evaluator evaluator) {
                    Hierarchy hierarchy = hierarchyCalc.evaluateHierarchy(evaluator);
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled()) {
                        TupleList result = new UnaryTupleList();
                        List<Member> memberList = result.slice(0);
                        HierarchyMemberTree hierarchyMemberTree;
                        try {
                            hierarchyMemberTree = hierarchyCache.getMemberTree((RolapCubeHierarchy) hierarchy);
                        } catch (ExecutionException | SQLException e) {
                            throw new MondrianException(e);
                        }
                        memberList.addAll(hierarchyMemberTree.getAllMembers());
                        memberList.addAll(evaluator.getSchemaReader().getCalculatedMembers(hierarchy));
                        return result;
                    } else {
                        return hierarchyMembers(hierarchy, evaluator, true);
                    }
                }
            };
        }
    });
    // <Level>.Members
    builder.define(LevelMembersFunDef.INSTANCE);
    // <Level>.AllMembers
    builder.define(new FunDefBase("AllMembers", "Returns a set that contains all members, including calculated members, of the specified level.", "pxl") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final LevelCalc levelCalc = compiler.compileLevel(call.getArg(0));
            return new AbstractListCalc(call, new Calc[] { levelCalc }) {

                public TupleList evaluateList(Evaluator evaluator) {
                    Level level = levelCalc.evaluateLevel(evaluator);
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled() && !level.getDimension().isMeasures()) {
                        assert level instanceof RolapCubeLevel;
                        TupleList result = new UnaryTupleList();
                        List<Member> memberList = result.slice(0);
                        HierarchyMemberTree hierarchyMemberTree;
                        try {
                            hierarchyMemberTree = hierarchyCache.getMemberTree(((RolapCubeLevel) level).getHierarchy());
                        } catch (ExecutionException | SQLException e) {
                            throw new MondrianException(e);
                        }
                        memberList.addAll(hierarchyMemberTree.getMembersByLevelDepth(level.getDepth()));
                        memberList.addAll(evaluator.getSchemaReader().getCalculatedMembers(level));
                        return result;
                    } else {
                        return levelMembers(level, evaluator, true);
                    }
                }
            };
        }
    });
    builder.define(XtdFunDef.MtdResolver);
    builder.define(OrderFunDef.Resolver);
    builder.define(UnorderFunDef.Resolver);
    builder.define(PeriodsToDateFunDef.Resolver);
    builder.define(XtdFunDef.QtdResolver);
    // StripCalculatedMembers(<Set>)
    builder.define(new FunDefBase("StripCalculatedMembers", "Removes calculated members from a set.", "fxx") {

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

                public TupleList evaluateList(Evaluator evaluator) {
                    TupleList list = listCalc.evaluateList(evaluator);
                    return removeCalculatedMembers(list);
                }
            };
        }
    });
    // <Member>.Siblings
    builder.define(new FunDefBase("Siblings", "Returns the siblings of a specified member, including the member itself.", "pxm") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
            return new AbstractListCalc(call, new Calc[] { memberCalc }) {

                public TupleList evaluateList(Evaluator evaluator) {
                    final Member member = memberCalc.evaluateMember(evaluator);
                    HierarchyCache hierarchyCache = CacheManager.getCacheManager().getHierarchyCache();
                    if (hierarchyCache.isCacheEnabled()) {
                        assert member instanceof RolapMember;
                        List<Member> siblings = new ArrayList<>();
                        if (member.isNull()) {
                            siblings = Collections.emptyList();
                        } else if (member.getParentMember() != null) {
                            siblings = FunUtil.getChildrenOfMember(member.getParentMember());
                        } else {
                            siblings.add(member.getHierarchy().getAllMember());
                        }
                        return new UnaryTupleList(siblings);
                    } else {
                        return new UnaryTupleList(memberSiblings(member, evaluator));
                    }
                }
            };
        }

        List<Member> memberSiblings(Member member, Evaluator evaluator) {
            if (member.isNull()) {
                // the null member has no siblings -- not even itself
                return Collections.emptyList();
            }
            Member parent = member.getParentMember();
            final SchemaReader schemaReader = evaluator.getSchemaReader();
            if (parent == null) {
                return schemaReader.getHierarchyRootMembers(member.getHierarchy());
            } else {
                return schemaReader.getMemberChildren(parent);
            }
        }
    });
    builder.define(StrToSetFunDef.Resolver);
    builder.define(SubsetFunDef.Resolver);
    builder.define(HeadTailFunDef.TailResolver);
    builder.define(ToggleDrillStateFunDef.Resolver);
    // Union(<Set Expression> ... [,ALL] )
    builder.define(UnionFunDef.UnionResolver);
    // <Set Expression> + <Set Expression>
    builder.define(UnionFunDef.AddUnionFunDef);
    builder.define(VisualTotalsFunDef.Resolver);
    builder.define(XtdFunDef.WtdResolver);
    builder.define(XtdFunDef.YtdResolver);
    // "<member> : <member>" operator
    builder.define(RangeFunDef.instance);
    // "{ <member> [,...] }" operator
    builder.define(SetFunDef.Resolver);
    builder.define(NativizeSetFunDef.Resolver);
    // 
    // STRING FUNCTIONS
    builder.define(FormatFunDef.Resolver);
    builder.define(SetToStrFunDef.instance);
    builder.define(TupleToStrFunDef.instance);
    // <Set>.Current
    if (false)
        builder.define(new FunDefBase("Current", "Returns the current tuple from a set during an iteration.", "ptx") {

            public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
                throw new UnsupportedOperationException();
            }
        });
    builder.define(SetItemFunDef.intResolver);
    builder.define(SetItemFunDef.stringResolver);
    builder.define(TupleItemFunDef.instance);
    builder.define(StrToTupleFunDef.Resolver);
    // special resolver for "()"
    builder.define(TupleFunDef.Resolver);
    // 
    // GENERIC VALUE FUNCTIONS
    builder.define(CoalesceEmptyFunDef.Resolver);
    builder.define(CaseTestFunDef.Resolver);
    builder.define(CaseMatchFunDef.Resolver);
    builder.define(PropertiesFunDef.Resolver);
    // FIXED SCOPE FUNCTION
    builder.define(FixedFunDef.Resolver);
    // Scope Function
    builder.define(ScopeFunDef.Resolver);
    // EXCLUDE SCOPE FUNCTION
    builder.define(ExcludeFunDef.Resolver);
    // 
    // PARAMETER FUNCTIONS
    builder.define(new ParameterFunDef.ParameterResolver());
    builder.define(new ParameterFunDef.ParamRefResolver());
    // 
    // OPERATORS
    // <Numeric Expression> * <Numeric Expression>
    builder.define(new FunDefBase("*", "Multiplies two numbers.", "innn") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0));
            final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1));
            return new AbstractDoubleCalc(call, new Calc[] { calc0, calc1 }) {

                public double evaluateDouble(Evaluator evaluator) {
                    final double v0 = calc0.evaluateDouble(evaluator);
                    final double v1 = calc1.evaluateDouble(evaluator);
                    // null.
                    if (v0 == DoubleNull || v1 == DoubleNull) {
                        return DoubleNull;
                    } else {
                        return v0 * v1;
                    }
                }
            };
        }
    });
    // <Numeric Expression> / <Numeric Expression>
    builder.define(new FunDefBase("/", "Divides two numbers.", "innn") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0));
            final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1));
            final boolean isNullDenominatorProducesNull = MondrianProperties.instance().NullDenominatorProducesNull.get();
            // conform to MSAS behavior.
            if (!isNullDenominatorProducesNull) {
                return new AbstractDoubleCalc(call, new Calc[] { calc0, calc1 }) {

                    public double evaluateDouble(Evaluator evaluator) {
                        final double v0 = calc0.evaluateDouble(evaluator);
                        final double v1 = calc1.evaluateDouble(evaluator);
                        // 
                        if (v0 == DoubleNull) {
                            return DoubleNull;
                        } else if (v1 == DoubleNull || v1 == 0.0) {
                            // Null only in denominator returns Infinity.
                            return MondrianProperties.instance().ReturnNullWhenDivideZero.get() ? DoubleNull : Double.POSITIVE_INFINITY;
                        } else {
                            return v0 / v1;
                        }
                    }
                };
            } else {
                return new AbstractDoubleCalc(call, new Calc[] { calc0, calc1 }) {

                    public double evaluateDouble(Evaluator evaluator) {
                        final double v0 = calc0.evaluateDouble(evaluator);
                        final double v1 = calc1.evaluateDouble(evaluator);
                        // DoubleNull.
                        if (v0 == DoubleNull || v1 == DoubleNull) {
                            return DoubleNull;
                        } else {
                            return v0 / v1;
                        }
                    }
                };
            }
        }
    });
    // - <Numeric Expression>
    builder.define(new FunDefBase("-", "Returns the negative of a number.", "Pnn") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DoubleCalc calc = compiler.compileDouble(call.getArg(0));
            return new AbstractDoubleCalc(call, new Calc[] { calc }) {

                public double evaluateDouble(Evaluator evaluator) {
                    final double v = calc.evaluateDouble(evaluator);
                    if (v == DoubleNull) {
                        return DoubleNull;
                    } else {
                        return -v;
                    }
                }
            };
        }
    });
    // <String Expression> || <String Expression>
    builder.define(new StringConcatFunDef("||", "Concatenates two strings.", "iSSS"));
    // <String Expression> + <String Expression>
    builder.define(new StringConcatFunDef("+", "Concatenates two strings.", "iSSS"));
    // <Logical Expression> AND <Logical Expression>
    builder.define(new FunDefBase("AND", "Returns the conjunction of two conditions.", "ibbb") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final BooleanCalc calc0 = compiler.compileBoolean(call.getArg(0));
            final BooleanCalc calc1 = compiler.compileBoolean(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    boolean b0 = calc0.evaluateBoolean(evaluator);
                    // referenced in the AND expression in a single query
                    if (!evaluator.isEvalAxes() && !b0) {
                        return false;
                    }
                    boolean b1 = calc1.evaluateBoolean(evaluator);
                    return b0 && b1;
                }
            };
        }
    });
    // <Logical Expression> OR <Logical Expression>
    builder.define(new FunDefBase("OR", "Returns the disjunction of two conditions.", "ibbb") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final BooleanCalc calc0 = compiler.compileBoolean(call.getArg(0));
            final BooleanCalc calc1 = compiler.compileBoolean(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    boolean b0 = calc0.evaluateBoolean(evaluator);
                    // referenced in the OR expression in a single query
                    if (!evaluator.isEvalAxes() && b0) {
                        return true;
                    }
                    boolean b1 = calc1.evaluateBoolean(evaluator);
                    return b0 || b1;
                }
            };
        }
    });
    // <Logical Expression> XOR <Logical Expression>
    builder.define(new FunDefBase("XOR", "Returns whether two conditions are mutually exclusive.", "ibbb") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final BooleanCalc calc0 = compiler.compileBoolean(call.getArg(0));
            final BooleanCalc calc1 = compiler.compileBoolean(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final boolean b0 = calc0.evaluateBoolean(evaluator);
                    final boolean b1 = calc1.evaluateBoolean(evaluator);
                    return b0 != b1;
                }
            };
        }
    });
    // NOT <Logical Expression>
    builder.define(new FunDefBase("NOT", "Returns the negation of a condition.", "Pbb") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final BooleanCalc calc = compiler.compileBoolean(call.getArg(0));
            return new AbstractBooleanCalc(call, new Calc[] { calc }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    return !calc.evaluateBoolean(evaluator);
                }
            };
        }
    });
    // <Value Expression> = <Value Expression>
    // <Value Expression> <> <Value Expression>
    LogicComparisonFunDef.define(builder);
    // <Numeric Expression> < <Numeric Expression>
    builder.define(new FunDefBase("<", "Returns whether an expression is less than another.", "ibnn") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0));
            final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final double v0 = calc0.evaluateDouble(evaluator);
                    final double v1 = calc1.evaluateDouble(evaluator);
                    if (Double.isNaN(v0) || Double.isNaN(v1) || v0 == DoubleNull || v1 == DoubleNull) {
                        return BooleanNull;
                    }
                    if (Math.abs(v0 - v1) < (1E-15)) {
                        return false;
                    } else {
                        return v0 < v1;
                    }
                }
            };
        }
    });
    // <String Expression> < <String Expression>
    builder.define(new FunDefBase("<", "Returns whether an expression is less than another.", "ibSS") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final StringCalc calc0 = compiler.compileString(call.getArg(0));
            final StringCalc calc1 = compiler.compileString(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final String b0 = calc0.evaluateString(evaluator);
                    final String b1 = calc1.evaluateString(evaluator);
                    if (b0 == null || b1 == null) {
                        return BooleanNull;
                    }
                    return b0.compareTo(b1) < 0;
                }
            };
        }
    });
    // <Numeric Expression> <= <Numeric Expression>
    builder.define(new FunDefBase("<=", "Returns whether an expression is less than or equal to another.", "ibnn") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0));
            final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final double v0 = calc0.evaluateDouble(evaluator);
                    final double v1 = calc1.evaluateDouble(evaluator);
                    if (Double.isNaN(v0) || Double.isNaN(v1) || v0 == DoubleNull || v1 == DoubleNull) {
                        return BooleanNull;
                    }
                    if (Math.abs(v0 - v1) < (1E-15)) {
                        return true;
                    } else {
                        return v0 <= v1;
                    }
                }
            };
        }
    });
    // <String Expression> <= <String Expression>
    builder.define(new FunDefBase("<=", "Returns whether an expression is less than or equal to another.", "ibSS") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final StringCalc calc0 = compiler.compileString(call.getArg(0));
            final StringCalc calc1 = compiler.compileString(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final String b0 = calc0.evaluateString(evaluator);
                    final String b1 = calc1.evaluateString(evaluator);
                    if (b0 == null || b1 == null) {
                        return BooleanNull;
                    }
                    return b0.compareTo(b1) <= 0;
                }
            };
        }
    });
    // <member Expression> <= <DateTime Expression>
    builder.define(new FunDefBase("<=", "Returns whether an expression is less than or equal to another.", "ibmD") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DateTimeCalc calc0 = compiler.compileDateTime(call.getArg(0));
            final DateTimeCalc calc1 = compiler.compileDateTime(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final Date b0 = calc0.evaluateDateTime(evaluator);
                    final Date b1 = calc1.evaluateDateTime(evaluator);
                    if (b0 == null || b1 == null) {
                        return BooleanNull;
                    }
                    return b0.compareTo(b1) <= 0;
                }
            };
        }
    });
    builder.define(new FunDefBase("<=", "Returns whether an expression is less than or equal to another.", "ibDD") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DateTimeCalc calc0 = compiler.compileDateTime(call.getArg(0));
            final DateTimeCalc calc1 = compiler.compileDateTime(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final Date b0 = calc0.evaluateDateTime(evaluator);
                    final Date b1 = calc1.evaluateDateTime(evaluator);
                    if (b0 == null || b1 == null) {
                        return BooleanNull;
                    }
                    return b0.compareTo(b1) <= 0;
                }
            };
        }
    });
    // <Numeric Expression> > <Numeric Expression>
    builder.define(new FunDefBase(">", "Returns whether an expression is greater than another.", "ibnn") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0));
            final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final double v0 = calc0.evaluateDouble(evaluator);
                    final double v1 = calc1.evaluateDouble(evaluator);
                    if (Double.isNaN(v0) || Double.isNaN(v1) || v0 == DoubleNull || v1 == DoubleNull) {
                        return BooleanNull;
                    }
                    if (Math.abs(v0 - v1) < (1E-15)) {
                        return false;
                    } else {
                        return v0 > v1;
                    }
                }
            };
        }
    });
    // <String Expression> > <String Expression>
    builder.define(new FunDefBase(">", "Returns whether an expression is greater than another.", "ibSS") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final StringCalc calc0 = compiler.compileString(call.getArg(0));
            final StringCalc calc1 = compiler.compileString(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final String b0 = calc0.evaluateString(evaluator);
                    final String b1 = calc1.evaluateString(evaluator);
                    if (b0 == null || b1 == null) {
                        return BooleanNull;
                    }
                    return b0.compareTo(b1) > 0;
                }
            };
        }
    });
    // <Numeric Expression> >= <Numeric Expression>
    builder.define(new FunDefBase(">=", "Returns whether an expression is greater than or equal to another.", "ibnn") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DoubleCalc calc0 = compiler.compileDouble(call.getArg(0));
            final DoubleCalc calc1 = compiler.compileDouble(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final double v0 = calc0.evaluateDouble(evaluator);
                    final double v1 = calc1.evaluateDouble(evaluator);
                    if (Double.isNaN(v0) || Double.isNaN(v1) || v0 == DoubleNull || v1 == DoubleNull) {
                        return BooleanNull;
                    }
                    if (Math.abs(v0 - v1) < (1E-15)) {
                        return true;
                    } else {
                        return v0 >= v1;
                    }
                }
            };
        }
    });
    // <String Expression> >= <String Expression>
    builder.define(new FunDefBase(">=", "Returns whether an expression is greater than or equal to another.", "ibSS") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final StringCalc calc0 = compiler.compileString(call.getArg(0));
            final StringCalc calc1 = compiler.compileString(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final String b0 = calc0.evaluateString(evaluator);
                    final String b1 = calc1.evaluateString(evaluator);
                    if (b0 == null || b1 == null) {
                        return BooleanNull;
                    }
                    return b0.compareTo(b1) >= 0;
                }
            };
        }
    });
    // <member Expression> >= <DateTime Expression>
    builder.define(new FunDefBase(">=", "Returns whether an expression is greater than or equal to another.", "ibmD") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DateTimeCalc calc0 = compiler.compileDateTime(call.getArg(0));
            final DateTimeCalc calc1 = compiler.compileDateTime(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final Date b0 = calc0.evaluateDateTime(evaluator);
                    final Date b1 = calc1.evaluateDateTime(evaluator);
                    if (b0 == null || b1 == null) {
                        return BooleanNull;
                    }
                    return b0.compareTo(b1) >= 0;
                }
            };
        }
    });
    builder.define(new FunDefBase(">=", "Returns whether an expression is greater than or equal to another.", "ibDD") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final DateTimeCalc calc0 = compiler.compileDateTime(call.getArg(0));
            final DateTimeCalc calc1 = compiler.compileDateTime(call.getArg(1));
            return new AbstractBooleanCalc(call, new Calc[] { calc0, calc1 }) {

                public boolean evaluateBoolean(Evaluator evaluator) {
                    final Date b0 = calc0.evaluateDateTime(evaluator);
                    final Date b1 = calc1.evaluateDateTime(evaluator);
                    if (b0 == null || b1 == null) {
                        return BooleanNull;
                    }
                    return b0.compareTo(b1) >= 0;
                }
            };
        }
    });
    // NON-STANDARD FUNCTIONS
    builder.define(NthQuartileFunDef.FirstQResolver);
    builder.define(NthQuartileFunDef.ThirdQResolver);
    builder.define(CalculatedChildFunDef.instance);
    builder.define(CastFunDef.Resolver);
    // UCase(<String Expression>)
    builder.define(new FunDefBase("UCase", "Returns a string that has been converted to uppercase", "fSS") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final Locale locale = compiler.getEvaluator().getConnectionLocale();
            final StringCalc stringCalc = compiler.compileString(call.getArg(0));
            return new AbstractStringCalc(call, new Calc[] { stringCalc }) {

                public String evaluateString(Evaluator evaluator) {
                    String value = stringCalc.evaluateString(evaluator);
                    return value.toUpperCase(locale);
                }
            };
        }
    });
    // Len(<String Expression>)
    builder.define(new FunDefBase("Len", "Returns the number of characters in a string", "fnS") {

        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
            final StringCalc stringCalc = compiler.compileString(call.getArg(0));
            return new AbstractIntegerCalc(call, new Calc[] { stringCalc }) {

                public int evaluateInteger(Evaluator evaluator) {
                    String value = stringCalc.evaluateString(evaluator);
                    if (value == null) {
                        return 0;
                    }
                    return value.length();
                }
            };
        }
    });
    // Define VBA functions.
    for (FunDef funDef : JavaFunDef.scan(Vba.class)) {
        builder.define(funDef);
    }
    // Define Excel functions.
    for (FunDef funDef : JavaFunDef.scan(Excel.class)) {
        builder.define(funDef);
    }
}
Also used : ValueCalc(mondrian.calc.impl.ValueCalc) Locale(java.util.Locale) ArrayList(java.util.ArrayList) RolapCubeHierarchy(mondrian.rolap.RolapCubeHierarchy) Hierarchy(mondrian.olap.Hierarchy) AbstractIntegerCalc(mondrian.calc.impl.AbstractIntegerCalc) IntegerCalc(mondrian.calc.IntegerCalc) RolapCubeLevel(mondrian.rolap.RolapCubeLevel) AbstractBooleanCalc(mondrian.calc.impl.AbstractBooleanCalc) List(java.util.List) ArrayList(java.util.ArrayList) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) TupleList(mondrian.calc.TupleList) ExpCompiler(mondrian.calc.ExpCompiler) Member(mondrian.olap.Member) RolapMember(mondrian.rolap.RolapMember) RolapCubeHierarchy(mondrian.rolap.RolapCubeHierarchy) AbstractStringCalc(mondrian.calc.impl.AbstractStringCalc) StringCalc(mondrian.calc.StringCalc) AbstractStringCalc(mondrian.calc.impl.AbstractStringCalc) HierarchyCache(io.kylin.mdx.rolap.cache.HierarchyCache) HierarchyCalc(mondrian.calc.HierarchyCalc) DateTimeCalc(mondrian.calc.DateTimeCalc) FunDef(mondrian.olap.FunDef) CalculatedChildFunDef(mondrian.olap.fun.extra.CalculatedChildFunDef) NthQuartileFunDef(mondrian.olap.fun.extra.NthQuartileFunDef) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) RolapCubeLevel(mondrian.rolap.RolapCubeLevel) Level(mondrian.olap.Level) HierarchyMemberTree(io.kylin.mdx.rolap.cache.HierarchyMemberTree) SchemaReader(mondrian.olap.SchemaReader) GenericCalc(mondrian.calc.impl.GenericCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) AbstractLevelCalc(mondrian.calc.impl.AbstractLevelCalc) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) AbstractDoubleCalc(mondrian.calc.impl.AbstractDoubleCalc) DoubleCalc(mondrian.calc.DoubleCalc) AbstractDoubleCalc(mondrian.calc.impl.AbstractDoubleCalc) PrintWriter(java.io.PrintWriter) Aggregator(mondrian.olap.Aggregator) AbstractDoubleCalc(mondrian.calc.impl.AbstractDoubleCalc) Calc(mondrian.calc.Calc) AbstractStringCalc(mondrian.calc.impl.AbstractStringCalc) AbstractBooleanCalc(mondrian.calc.impl.AbstractBooleanCalc) StringCalc(mondrian.calc.StringCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) HierarchyCalc(mondrian.calc.HierarchyCalc) DateTimeCalc(mondrian.calc.DateTimeCalc) GenericCalc(mondrian.calc.impl.GenericCalc) ValueCalc(mondrian.calc.impl.ValueCalc) AbstractIntegerCalc(mondrian.calc.impl.AbstractIntegerCalc) DoubleCalc(mondrian.calc.DoubleCalc) BooleanCalc(mondrian.calc.BooleanCalc) LevelCalc(mondrian.calc.LevelCalc) MemberCalc(mondrian.calc.MemberCalc) IntegerCalc(mondrian.calc.IntegerCalc) AbstractMemberCalc(mondrian.calc.impl.AbstractMemberCalc) AbstractLevelCalc(mondrian.calc.impl.AbstractLevelCalc) AbstractMemberCalc(mondrian.calc.impl.AbstractMemberCalc) LevelCalc(mondrian.calc.LevelCalc) AbstractLevelCalc(mondrian.calc.impl.AbstractLevelCalc) Evaluator(mondrian.olap.Evaluator) OlapElement(mondrian.olap.OlapElement) Date(java.util.Date) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) TupleList(mondrian.calc.TupleList) LevelType(mondrian.olap.type.LevelType) Type(mondrian.olap.type.Type) RolapMember(mondrian.rolap.RolapMember) Cube(mondrian.olap.Cube) MemberCalc(mondrian.calc.MemberCalc) AbstractMemberCalc(mondrian.calc.impl.AbstractMemberCalc) ResolvedFunCall(mondrian.mdx.ResolvedFunCall) Exp(mondrian.olap.Exp) MondrianException(mondrian.olap.MondrianException) AbstractIntegerCalc(mondrian.calc.impl.AbstractIntegerCalc) Validator(mondrian.olap.Validator) AbstractBooleanCalc(mondrian.calc.impl.AbstractBooleanCalc) BooleanCalc(mondrian.calc.BooleanCalc)

Aggregations

Cube (mondrian.olap.Cube)10 Member (mondrian.olap.Member)5 ArrayList (java.util.ArrayList)4 CacheControl (mondrian.olap.CacheControl)4 Hierarchy (mondrian.olap.Hierarchy)3 PrintWriter (java.io.PrintWriter)2 List (java.util.List)2 Locale (java.util.Locale)2 BooleanCalc (mondrian.calc.BooleanCalc)2 Calc (mondrian.calc.Calc)2 DoubleCalc (mondrian.calc.DoubleCalc)2 ExpCompiler (mondrian.calc.ExpCompiler)2 HierarchyCalc (mondrian.calc.HierarchyCalc)2 IntegerCalc (mondrian.calc.IntegerCalc)2 LevelCalc (mondrian.calc.LevelCalc)2 ListCalc (mondrian.calc.ListCalc)2 MemberCalc (mondrian.calc.MemberCalc)2 StringCalc (mondrian.calc.StringCalc)2 TupleList (mondrian.calc.TupleList)2 AbstractBooleanCalc (mondrian.calc.impl.AbstractBooleanCalc)2