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) 2006-2009 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.olap.fun; 011 012import mondrian.calc.*; 013import mondrian.calc.impl.AbstractMemberCalc; 014import mondrian.mdx.ResolvedFunCall; 015import mondrian.olap.*; 016 017/** 018 * Definition of the <code>Lead</code> and <code>Lag</code> MDX functions. 019 * 020 * @author jhyde 021 * @since Mar 23, 2006 022 */ 023class LeadLagFunDef extends FunDefBase { 024 static final ReflectiveMultiResolver LagResolver = 025 new ReflectiveMultiResolver( 026 "Lag", 027 "<Member>.Lag(<Numeric Expression>)", 028 "Returns a member further along the specified member's dimension.", 029 new String[]{"mmmn"}, 030 LeadLagFunDef.class); 031 032 static final ReflectiveMultiResolver LeadResolver = 033 new ReflectiveMultiResolver( 034 "Lead", 035 "<Member>.Lead(<Numeric Expression>)", 036 "Returns a member further along the specified member's dimension.", 037 new String[]{"mmmn"}, 038 LeadLagFunDef.class); 039 040 public LeadLagFunDef(FunDef dummyFunDef) { 041 super(dummyFunDef); 042 } 043 044 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 045 final MemberCalc memberCalc = 046 compiler.compileMember(call.getArg(0)); 047 final IntegerCalc integerCalc = 048 compiler.compileInteger(call.getArg(1)); 049 final boolean lag = call.getFunName().equals("Lag"); 050 return new AbstractMemberCalc( 051 call, 052 new Calc[] {memberCalc, integerCalc}) 053 { 054 public Member evaluateMember(Evaluator evaluator) { 055 Member member = memberCalc.evaluateMember(evaluator); 056 int n = integerCalc.evaluateInteger(evaluator); 057 if (lag) { 058 if (n == Integer.MIN_VALUE) { 059 // Bump up lagValue by one, otherwise -n (used 060 // in the getLeadMember call below) is out of 061 // range because Integer.MAX_VALUE == 062 // -(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