001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2009-2009 Pentaho and others
008// All Rights Reserved.
009*/
010package mondrian.olap.fun;
011
012import mondrian.calc.*;
013import mondrian.calc.impl.AbstractHierarchyCalc;
014import mondrian.mdx.ResolvedFunCall;
015import mondrian.olap.*;
016import mondrian.olap.type.HierarchyType;
017import mondrian.olap.type.Type;
018import mondrian.rolap.RolapCube;
019import mondrian.rolap.RolapHierarchy;
020
021import java.util.List;
022
023/**
024 * Definition of the <code>Dimensions(&lt;Numeric Expression&gt;)</code>
025 * MDX builtin function.
026 *
027 * <p>NOTE: Actually returns a hierarchy. This is consistent with Analysis
028 * Services.
029 *
030 * @author jhyde
031 * @since Jul 20, 2009
032 */
033class DimensionsNumericFunDef extends FunDefBase {
034    public static final FunDefBase INSTANCE = new DimensionsNumericFunDef();
035
036    private DimensionsNumericFunDef() {
037        super(
038            "Dimensions",
039            "Returns the hierarchy whose zero-based position within the cube "
040            + "is specified by a numeric expression.",
041            "fhn");
042    }
043
044    public Type getResultType(Validator validator, Exp[] args) {
045        return HierarchyType.Unknown;
046    }
047
048    public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler)
049    {
050        final IntegerCalc integerCalc =
051            compiler.compileInteger(call.getArg(0));
052        return new AbstractHierarchyCalc(call, new Calc[] {integerCalc})
053        {
054            public Hierarchy evaluateHierarchy(Evaluator evaluator) {
055                int n = integerCalc.evaluateInteger(evaluator);
056                return nthHierarchy(evaluator, n);
057            }
058        };
059    }
060
061    RolapHierarchy nthHierarchy(Evaluator evaluator, int n) {
062        RolapCube cube = (RolapCube) evaluator.getCube();
063        List<RolapHierarchy> hierarchies = cube.getHierarchies();
064        if (n >= hierarchies.size() || n < 0) {
065            throw newEvalException(
066                this, "Index '" + n + "' out of bounds");
067        }
068        return hierarchies.get(n);
069    }
070}
071
072// End DimensionsNumericFunDef.java