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) 2005-2005 Julian Hyde 008// Copyright (C) 2005-2011 Pentaho 009// All Rights Reserved. 010*/ 011package mondrian.olap.fun; 012 013import mondrian.calc.*; 014import mondrian.calc.impl.AbstractListCalc; 015import mondrian.calc.impl.UnaryTupleList; 016import mondrian.mdx.ResolvedFunCall; 017import mondrian.olap.DimensionType; 018import mondrian.olap.*; 019import mondrian.olap.LevelType; 020import mondrian.olap.type.*; 021import mondrian.resource.MondrianResource; 022import mondrian.rolap.RolapCube; 023import mondrian.rolap.RolapHierarchy; 024 025/** 026 * Definition of <code>Ytd</code>, <code>Qtd</code>, <code>Mtd</code>, 027 * and <code>Wtd</code> MDX builtin functions. 028 * 029 * @author jhyde 030 * @since Mar 23, 2006 031 */ 032class XtdFunDef extends FunDefBase { 033 private final LevelType levelType; 034 035 static final ResolverImpl MtdResolver = 036 new ResolverImpl( 037 "Mtd", 038 "Mtd([<Member>])", 039 "A shortcut function for the PeriodsToDate function that specifies the level to be Month.", 040 new String[]{"fx", "fxm"}, 041 LevelType.TimeMonths); 042 043 static final ResolverImpl QtdResolver = 044 new ResolverImpl( 045 "Qtd", 046 "Qtd([<Member>])", 047 "A shortcut function for the PeriodsToDate function that specifies the level to be Quarter.", 048 new String[]{"fx", "fxm"}, 049 LevelType.TimeQuarters); 050 051 static final ResolverImpl WtdResolver = 052 new ResolverImpl( 053 "Wtd", 054 "Wtd([<Member>])", 055 "A shortcut function for the PeriodsToDate function that specifies the level to be Week.", 056 new String[]{"fx", "fxm"}, 057 LevelType.TimeWeeks); 058 059 static final ResolverImpl YtdResolver = 060 new ResolverImpl( 061 "Ytd", 062 "Ytd([<Member>])", 063 "A shortcut function for the PeriodsToDate function that specifies the level to be Year.", 064 new String[]{"fx", "fxm"}, 065 LevelType.TimeYears); 066 067 public XtdFunDef(FunDef dummyFunDef, LevelType levelType) { 068 super(dummyFunDef); 069 this.levelType = levelType; 070 } 071 072 public Type getResultType(Validator validator, Exp[] args) { 073 if (args.length == 0) { 074 // With no args, the default implementation cannot 075 // guess the hierarchy. 076 RolapHierarchy defaultTimeHierarchy = 077 ((RolapCube) validator.getQuery().getCube()).getTimeHierarchy( 078 getName()); 079 return new SetType(MemberType.forHierarchy(defaultTimeHierarchy)); 080 } 081 final Type type = args[0].getType(); 082 if (type.getDimension().getDimensionType() 083 != DimensionType.TimeDimension) 084 { 085 throw MondrianResource.instance().TimeArgNeeded.ex(getName()); 086 } 087 return super.getResultType(validator, args); 088 } 089 090 private Level getLevel(Evaluator evaluator) { 091 switch (levelType) { 092 case TimeYears: 093 return evaluator.getCube().getYearLevel(); 094 case TimeQuarters: 095 return evaluator.getCube().getQuarterLevel(); 096 case TimeMonths: 097 return evaluator.getCube().getMonthLevel(); 098 case TimeWeeks: 099 return evaluator.getCube().getWeekLevel(); 100 case TimeDays: 101 return evaluator.getCube().getWeekLevel(); 102 default: 103 throw Util.badValue(levelType); 104 } 105 } 106 107 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 108 final Level level = getLevel(compiler.getEvaluator()); 109 switch (call.getArgCount()) { 110 case 0: 111 return new AbstractListCalc(call, new Calc[0]) { 112 public TupleList evaluateList(Evaluator evaluator) { 113 return new UnaryTupleList( 114 periodsToDate(evaluator, level, null)); 115 } 116 117 public boolean dependsOn(Hierarchy hierarchy) { 118 return hierarchy.getDimension().getDimensionType() 119 == mondrian.olap.DimensionType.TimeDimension; 120 } 121 }; 122 default: 123 final MemberCalc memberCalc = 124 compiler.compileMember(call.getArg(0)); 125 return new AbstractListCalc(call, new Calc[] {memberCalc}) { 126 public TupleList evaluateList(Evaluator evaluator) { 127 return new UnaryTupleList( 128 periodsToDate( 129 evaluator, 130 level, 131 memberCalc.evaluateMember(evaluator))); 132 } 133 }; 134 } 135 } 136 137 private static class ResolverImpl extends MultiResolver { 138 private final LevelType levelType; 139 140 public ResolverImpl( 141 String name, 142 String signature, 143 String description, 144 String[] signatures, 145 LevelType levelType) 146 { 147 super(name, signature, description, signatures); 148 this.levelType = levelType; 149 } 150 151 protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) { 152 return new XtdFunDef(dummyFunDef, levelType); 153 } 154 } 155} 156 157// End XtdFunDef.java