001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/fun/DistinctFunDef.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) 2007-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 java.util.ArrayList; 013 import java.util.Arrays; 014 import java.util.HashSet; 015 import java.util.List; 016 import java.util.Set; 017 018 import mondrian.calc.*; 019 import mondrian.calc.impl.AbstractListCalc; 020 import mondrian.mdx.ResolvedFunCall; 021 import mondrian.olap.Evaluator; 022 import mondrian.olap.Member; 023 024 /** 025 * Definition of the <code>Distinct</code> MDX function. 026 * 027 * <p>Syntax: 028 * <blockquote><code>Distinct(<Set>)</code></blockquote> 029 * 030 * @author jhyde 031 * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/DistinctFunDef.java#3 $ 032 * @since Jun 10, 2007 033 */ 034 class DistinctFunDef extends FunDefBase { 035 public static final DistinctFunDef instance = new DistinctFunDef(); 036 037 private DistinctFunDef() { 038 super("Distinct", 039 "Eliminates duplicate tuples from a set.", 040 "fxx"); 041 } 042 043 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 044 final ListCalc listCalc = 045 compiler.compileList(call.getArg(0)); 046 return new CalcImpl(call, listCalc); 047 } 048 049 static class CalcImpl extends AbstractListCalc { 050 private final ListCalc listCalc; 051 052 public CalcImpl(ResolvedFunCall call, ListCalc listCalc) { 053 super(call, new Calc[]{listCalc}); 054 this.listCalc = listCalc; 055 } 056 057 public List evaluateList(Evaluator evaluator) { 058 List list = listCalc.evaluateList(evaluator); 059 return distinct(list); 060 } 061 062 static List<Object> distinct(List list) { 063 Set<MemberHelper> set = new HashSet<MemberHelper>(list.size()); 064 List<Object> result = new ArrayList<Object>(); 065 066 for (Object element : list) { 067 MemberHelper lookupObj = new MemberHelper(element); 068 069 if (set.add(lookupObj)) { 070 result.add(element); 071 } 072 } 073 return result; 074 } 075 076 public List<Member> evaluateMemberList(Evaluator evaluator) { 077 List<Member> list = 078 ((MemberListCalc) listCalc).evaluateMemberList(evaluator); 079 Set<Member> set = new HashSet<Member>(list.size()); 080 List<Member> result = new ArrayList<Member>(); 081 for (Member element : list) { 082 if (set.add(element)) { 083 result.add(element); 084 } 085 } 086 return result; 087 } 088 089 public List<Member[]> evaluateTupleList(Evaluator evaluator) { 090 List<Member[]> list = 091 ((TupleListCalc) listCalc).evaluateTupleList(evaluator); 092 Set<List<Member>> set = new HashSet<List<Member>>(list.size()); 093 List<Member[]> result = new ArrayList<Member[]>(); 094 for (Member[] element : list) { 095 if (set.add(Arrays.asList(element))) { 096 result.add(element); 097 } 098 } 099 return result; 100 } 101 } 102 } 103 104 // End DistinctFunDef.java