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) 2007-2011 Pentaho
008// All Rights Reserved.
009*/
010package mondrian.olap.fun;
011
012import mondrian.calc.*;
013import mondrian.calc.impl.AbstractListCalc;
014import mondrian.mdx.ResolvedFunCall;
015import mondrian.olap.Evaluator;
016import mondrian.olap.Member;
017
018import java.util.*;
019
020/**
021 * Definition of the <code>Distinct</code> MDX function.
022 *
023 * <p>Syntax:
024 * <blockquote><code>Distinct(&lt;Set&gt;)</code></blockquote>
025 *
026 * @author jhyde
027 * @since Jun 10, 2007
028*/
029class DistinctFunDef extends FunDefBase {
030    public static final DistinctFunDef instance = new DistinctFunDef();
031
032    private DistinctFunDef() {
033        super(
034            "Distinct",
035            "Eliminates duplicate tuples from a set.",
036            "fxx");
037    }
038
039    public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
040        final ListCalc listCalc =
041            compiler.compileList(call.getArg(0));
042        return new CalcImpl(call, listCalc);
043    }
044
045    static class CalcImpl extends AbstractListCalc {
046        private final ListCalc listCalc;
047
048        public CalcImpl(ResolvedFunCall call, ListCalc listCalc) {
049            super(call, new Calc[]{listCalc});
050            this.listCalc = listCalc;
051        }
052
053        public TupleList evaluateList(Evaluator evaluator) {
054            TupleList list = listCalc.evaluateList(evaluator);
055            Set<List<Member>> set = new HashSet<List<Member>>(list.size());
056            TupleList result = list.cloneList(list.size());
057            for (List<Member> element : list) {
058                if (set.add(element)) {
059                    result.add(element);
060                }
061            }
062            return result;
063        }
064    }
065}
066
067// End DistinctFunDef.java