001    /*
002    // $Id: //open/mondrian/src/main/mondrian/olap/fun/extra/NthQuartileFunDef.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) 2006-2007 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.extra;
011    
012    import mondrian.calc.Calc;
013    import mondrian.calc.DoubleCalc;
014    import mondrian.calc.ExpCompiler;
015    import mondrian.calc.ListCalc;
016    import mondrian.calc.impl.AbstractDoubleCalc;
017    import mondrian.calc.impl.ValueCalc;
018    import mondrian.mdx.ResolvedFunCall;
019    import mondrian.olap.Dimension;
020    import mondrian.olap.Evaluator;
021    import mondrian.olap.FunDef;
022    import mondrian.olap.fun.AbstractAggregateFunDef;
023    import mondrian.olap.fun.MultiResolver;
024    import mondrian.olap.fun.ReflectiveMultiResolver;
025    
026    import java.util.List;
027    
028    /**
029     * Definition of the <code>FirstQ</code> and <code>ThirdQ</code> MDX extension functions.
030     *
031     * <p>These functions are not standard.
032     *
033     * @author jhyde
034     * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/extra/NthQuartileFunDef.java#3 $
035     * @since Mar 23, 2006
036     */
037    public class NthQuartileFunDef extends AbstractAggregateFunDef {
038        private final int range;
039    
040        public static final MultiResolver ThirdQResolver = new ReflectiveMultiResolver(
041                "ThirdQ",
042                "ThirdQ(<Set>[, <Numeric Expression>])",
043                "Returns the 3rd quartile value of a numeric expression evaluated over a set.",
044                new String[]{"fnx", "fnxn"},
045            NthQuartileFunDef.class);
046    
047        public static final MultiResolver FirstQResolver = new ReflectiveMultiResolver(
048                "FirstQ",
049                "FirstQ(<Set>[, <Numeric Expression>])",
050                "Returns the 1st quartile value of a numeric expression evaluated over a set.",
051                new String[]{"fnx", "fnxn"},
052                NthQuartileFunDef.class);
053    
054        public NthQuartileFunDef(FunDef dummyFunDef) {
055            super(dummyFunDef);
056            this.range = dummyFunDef.getName().equals("FirstQ") ? 1 : 3;
057        }
058    
059        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
060            final ListCalc listCalc =
061                    compiler.compileList(call.getArg(0));
062            final DoubleCalc doubleCalc =
063                    call.getArgCount() > 1 ?
064                    compiler.compileDouble(call.getArg(1)) :
065                    new ValueCalc(call);
066            return new AbstractDoubleCalc(call, new Calc[] {listCalc, doubleCalc}) {
067                public double evaluateDouble(Evaluator evaluator) {
068                    List members = evaluateCurrentList(listCalc, evaluator);
069                    return quartile(evaluator.push(), members, doubleCalc, range);
070                }
071    
072                public boolean dependsOn(Dimension dimension) {
073                    return anyDependsButFirst(getCalcs(), dimension);
074                }
075            };
076        }
077    }
078    
079    // End NthQuartileFunDef.java