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