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