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.AbstractDoubleCalc;
014import mondrian.calc.impl.ValueCalc;
015import mondrian.mdx.ResolvedFunCall;
016import mondrian.olap.*;
017
018/**
019 * Definition of the <code>Avg</code> MDX function.
020 *
021 * @author jhyde
022 * @since Mar 23, 2006
023 */
024class AvgFunDef extends AbstractAggregateFunDef {
025    static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver(
026        "Avg",
027            "Avg(<Set>[, <Numeric Expression>])",
028            "Returns the average value of a numeric expression evaluated over a set.",
029            new String[]{"fnx", "fnxn"},
030            AvgFunDef.class);
031
032    public AvgFunDef(FunDef dummyFunDef) {
033        super(dummyFunDef);
034    }
035
036    public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
037        final ListCalc listCalc = compiler.compileList(call.getArg(0));
038        final Calc calc = call.getArgCount() > 1
039            ? compiler.compileScalar(call.getArg(1), true)
040            : new ValueCalc(call);
041        return new AbstractDoubleCalc(call, new Calc[]{listCalc, calc}) {
042            public double evaluateDouble(Evaluator evaluator) {
043                TupleList memberList = evaluateCurrentList(listCalc, evaluator);
044                final int savepoint = evaluator.savepoint();
045                evaluator.setNonEmpty(false);
046                try {
047                    final double avg =
048                        (Double) avg(
049                            evaluator, memberList, calc);
050                    return avg;
051                } finally {
052                    evaluator.restore(savepoint);
053                }
054            }
055
056            public boolean dependsOn(Hierarchy hierarchy) {
057                return anyDependsButFirst(getCalcs(), hierarchy);
058            }
059        };
060    }
061}
062
063// End AvgFunDef.java