001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/fun/LeadLagFunDef.java#3 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2006-2008 Julian Hyde 007 // All Rights Reserved. 008 // You must accept the terms of that agreement to use this software. 009 */ 010 package mondrian.olap.fun; 011 012 import mondrian.olap.FunDef; 013 import mondrian.olap.Member; 014 import mondrian.olap.Evaluator; 015 import mondrian.calc.Calc; 016 import mondrian.calc.ExpCompiler; 017 import mondrian.calc.MemberCalc; 018 import mondrian.calc.IntegerCalc; 019 import mondrian.calc.impl.AbstractMemberCalc; 020 import mondrian.mdx.ResolvedFunCall; 021 022 /** 023 * Definition of the <code>Lead</code> and <code>Lag</code> MDX functions. 024 * 025 * @author jhyde 026 * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/LeadLagFunDef.java#3 $ 027 * @since Mar 23, 2006 028 */ 029 class LeadLagFunDef extends FunDefBase { 030 static final ReflectiveMultiResolver LagResolver = new ReflectiveMultiResolver( 031 "Lag", 032 "<Member>.Lag(<Numeric Expression>)", 033 "Returns a member further along the specified member's dimension.", 034 new String[]{"mmmn"}, 035 LeadLagFunDef.class); 036 037 static final ReflectiveMultiResolver LeadResolver = new ReflectiveMultiResolver( 038 "Lead", 039 "<Member>.Lead(<Numeric Expression>)", 040 "Returns a member further along the specified member's dimension.", 041 new String[]{"mmmn"}, 042 LeadLagFunDef.class); 043 044 public LeadLagFunDef(FunDef dummyFunDef) { 045 super(dummyFunDef); 046 } 047 048 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 049 final MemberCalc memberCalc = 050 compiler.compileMember(call.getArg(0)); 051 final IntegerCalc integerCalc = 052 compiler.compileInteger(call.getArg(1)); 053 final boolean lag = call.getFunName().equals("Lag"); 054 return new AbstractMemberCalc(call, new Calc[] {memberCalc, integerCalc}) { 055 public Member evaluateMember(Evaluator evaluator) { 056 Member member = memberCalc.evaluateMember(evaluator); 057 int n = integerCalc.evaluateInteger(evaluator); 058 if (lag) { 059 if (n == Integer.MIN_VALUE) { 060 // bump up lagValue by one 061 // otherwise -n(used in the getLeadMember call below)is out of range 062 // because Integer.MAX_VALUE == -(Integer.MIN_VALUE + 1) 063 n += 1; 064 } 065 066 n = -n; 067 } 068 return evaluator.getSchemaReader().getLeadMember(member, n); 069 } 070 }; 071 } 072 } 073 074 // End LeadLagFunDef.java