/* // This software is subject to the terms of the Eclipse Public License v1.0 // Agreement, available at the following URL: // http://www.eclipse.org/legal/epl-v10.html. // You must accept the terms of that agreement to use this software. // // Copyright (C) 2005-2005 Julian Hyde // Copyright (C) 2005-2011 Pentaho // All Rights Reserved. */ package mondrian.olap.fun; import mondrian.calc.*; import mondrian.calc.impl.AbstractListCalc; import mondrian.calc.impl.UnaryTupleList; import mondrian.mdx.ResolvedFunCall; import mondrian.olap.DimensionType; import mondrian.olap.*; import mondrian.olap.LevelType; import mondrian.olap.type.*; import mondrian.resource.MondrianResource; import mondrian.rolap.RolapCube; import mondrian.rolap.RolapHierarchy; /** * Definition of <code>Ytd</code>, <code>Qtd</code>, <code>Mtd</code>, * and <code>Wtd</code> MDX builtin functions. * * @author jhyde * @since Mar 23, 2006 */ class XtdFunDef extends FunDefBase { private final LevelType levelType; static final ResolverImpl MtdResolver = new ResolverImpl( "Mtd", "Mtd([<Member>])", "A shortcut function for the PeriodsToDate function that specifies the level to be Month.", new String[]{"fx", "fxm"}, LevelType.TimeMonths); static final ResolverImpl QtdResolver = new ResolverImpl( "Qtd", "Qtd([<Member>])", "A shortcut function for the PeriodsToDate function that specifies the level to be Quarter.", new String[]{"fx", "fxm"}, LevelType.TimeQuarters); static final ResolverImpl WtdResolver = new ResolverImpl( "Wtd", "Wtd([<Member>])", "A shortcut function for the PeriodsToDate function that specifies the level to be Week.", new String[]{"fx", "fxm"}, LevelType.TimeWeeks); static final ResolverImpl YtdResolver = new ResolverImpl( "Ytd", "Ytd([<Member>])", "A shortcut function for the PeriodsToDate function that specifies the level to be Year.", new String[]{"fx", "fxm"}, LevelType.TimeYears); public XtdFunDef(FunDef dummyFunDef, LevelType levelType) { super(dummyFunDef); this.levelType = levelType; } public Type getResultType(Validator validator, Exp[] args) { if (args.length == 0) { // With no args, the default implementation cannot // guess the hierarchy. RolapHierarchy defaultTimeHierarchy = ((RolapCube) validator.getQuery().getCube()).getTimeHierarchy( getName()); return new SetType(MemberType.forHierarchy(defaultTimeHierarchy)); } final Type type = args[0].getType(); if (type.getDimension().getDimensionType() != DimensionType.TimeDimension) { throw MondrianResource.instance().TimeArgNeeded.ex(getName()); } return super.getResultType(validator, args); } private Level getLevel(Evaluator evaluator) { switch (levelType) { case TimeYears: return evaluator.getCube().getYearLevel(); case TimeQuarters: return evaluator.getCube().getQuarterLevel(); case TimeMonths: return evaluator.getCube().getMonthLevel(); case TimeWeeks: return evaluator.getCube().getWeekLevel(); case TimeDays: return evaluator.getCube().getWeekLevel(); default: throw Util.badValue(levelType); } } public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { final Level level = getLevel(compiler.getEvaluator()); switch (call.getArgCount()) { case 0: return new AbstractListCalc(call, new Calc[0]) { public TupleList evaluateList(Evaluator evaluator) { return new UnaryTupleList( periodsToDate(evaluator, level, null)); } public boolean dependsOn(Hierarchy hierarchy) { return hierarchy.getDimension().getDimensionType() == mondrian.olap.DimensionType.TimeDimension; } }; default: final MemberCalc memberCalc = compiler.compileMember(call.getArg(0)); return new AbstractListCalc(call, new Calc[] {memberCalc}) { public TupleList evaluateList(Evaluator evaluator) { return new UnaryTupleList( periodsToDate( evaluator, level, memberCalc.evaluateMember(evaluator))); } }; } } private static class ResolverImpl extends MultiResolver { private final LevelType levelType; public ResolverImpl( String name, String signature, String description, String[] signatures, LevelType levelType) { super(name, signature, description, signatures); this.levelType = levelType; } protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) { return new XtdFunDef(dummyFunDef, levelType); } } } // End XtdFunDef.java