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.*; 016import mondrian.olap.type.*; 017 018/** 019 * Definition of the <code><Tuple>.Item</code> MDX function. 020 * 021 * <p>Syntax: 022 * <blockquote><code> 023 * <Tuple>.Item(<Index>)<br/> 024 * </code></blockquote> 025 * 026 * @author jhyde 027 * @since Mar 23, 2006 028 */ 029class TupleItemFunDef extends FunDefBase { 030 static final TupleItemFunDef instance = new TupleItemFunDef(); 031 032 private TupleItemFunDef() { 033 super( 034 "Item", 035 "Returns a member from the tuple specified in <Tuple>. The member to be returned is specified by the zero-based position of the member in the set in <Index>.", 036 "mmtn"); 037 } 038 039 public Type getResultType(Validator validator, Exp[] args) { 040 // Suppose we are called as follows: 041 // ([Gender].CurrentMember, [Store].CurrentMember).Item(n) 042 // 043 // We know that our result is a member type, but we don't 044 // know which dimension. 045 return MemberType.Unknown; 046 } 047 048 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 049 final Type type = call.getArg(0).getType(); 050 if (type instanceof MemberType) { 051 final MemberCalc memberCalc = 052 compiler.compileMember(call.getArg(0)); 053 final IntegerCalc indexCalc = 054 compiler.compileInteger(call.getArg(1)); 055 return new AbstractMemberCalc( 056 call, new Calc[] {memberCalc, indexCalc}) 057 { 058 public Member evaluateMember(Evaluator evaluator) { 059 final Member member = 060 memberCalc.evaluateMember(evaluator); 061 final int index = 062 indexCalc.evaluateInteger(evaluator); 063 if (index != 0) { 064 return null; 065 } 066 return member; 067 } 068 }; 069 } else { 070 final TupleCalc tupleCalc = 071 compiler.compileTuple(call.getArg(0)); 072 final IntegerCalc indexCalc = 073 compiler.compileInteger(call.getArg(1)); 074 return new AbstractMemberCalc( 075 call, new Calc[] {tupleCalc, indexCalc}) 076 { 077 final Member[] nullTupleMembers = 078 makeNullTuple((TupleType) tupleCalc.getType()); 079 public Member evaluateMember(Evaluator evaluator) { 080 final Member[] members = 081 tupleCalc.evaluateTuple(evaluator); 082 assert members == null 083 || members.length == nullTupleMembers.length; 084 final int index = indexCalc.evaluateInteger(evaluator); 085 if (members == null) { 086 return nullTupleMembers[index]; 087 } 088 if (index >= members.length || index < 0) { 089 return null; 090 } 091 return members[index]; 092 } 093 }; 094 } 095 } 096} 097 098// End TupleItemFunDef.java