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-2011 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.olap.fun; 011 012import mondrian.calc.*; 013import mondrian.calc.impl.AbstractListCalc; 014import mondrian.calc.impl.ArrayTupleList; 015import mondrian.mdx.ResolvedFunCall; 016import mondrian.olap.*; 017 018import java.util.*; 019 020/** 021 * Definition of the <code>Except</code> MDX function. 022 * 023 * @author jhyde 024 * @since Mar 23, 2006 025 */ 026class ExceptFunDef extends FunDefBase { 027 static final ReflectiveMultiResolver Resolver = 028 new ReflectiveMultiResolver( 029 "Except", 030 "Except(<Set1>, <Set2>[, ALL])", 031 "Finds the difference between two sets, optionally retaining duplicates.", 032 new String[]{"fxxx", "fxxxy"}, 033 ExceptFunDef.class); 034 035 public ExceptFunDef(FunDef dummyFunDef) { 036 super(dummyFunDef); 037 } 038 039 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 040 // todo: implement ALL 041 final ListCalc listCalc0 = compiler.compileList(call.getArg(0)); 042 final ListCalc listCalc1 = compiler.compileList(call.getArg(1)); 043 return new AbstractListCalc(call, new Calc[] {listCalc0, listCalc1}) 044 { 045 public TupleList evaluateList(Evaluator evaluator) { 046 TupleList list0 = listCalc0.evaluateList(evaluator); 047 if (list0.isEmpty()) { 048 return list0; 049 } 050 TupleList list1 = listCalc1.evaluateList(evaluator); 051 if (list1.isEmpty()) { 052 return list0; 053 } 054 final Set<List<Member>> set1 = new HashSet<List<Member>>(list1); 055 final TupleList result = 056 new ArrayTupleList(list0.getArity(), list0.size()); 057 for (List<Member> tuple1 : list0) { 058 if (!set1.contains(tuple1)) { 059 result.add(tuple1); 060 } 061 } 062 return result; 063 } 064 }; 065 } 066} 067 068// End ExceptFunDef.java