001    /*
002    // This software is subject to the terms of the Common Public License
003    // Agreement, available at the following URL:
004    // http://www.opensource.org/licenses/cpl.html.
005    // Copyright (C) 2008-2008 Julian Hyde
006    // All Rights Reserved.
007    // You must accept the terms of that agreement to use this software.
008    */
009    package mondrian.olap.fun;
010    
011    import mondrian.calc.*;
012    import mondrian.calc.impl.*;
013    import mondrian.mdx.ResolvedFunCall;
014    import mondrian.olap.*;
015    import mondrian.olap.type.Type;
016    import mondrian.olap.type.TypeUtil;
017    
018    /**
019     * Definition of the <code>Iif</code> MDX function.
020     *
021     * @author jhyde
022     * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/IifFunDef.java#2 $
023     * @since Jan 17, 2008
024     */
025    public class IifFunDef extends FunDefBase {
026        protected IifFunDef(
027            String name,
028            String description,
029            String flags)
030        {
031            super(name, description, flags);
032        }
033    
034        public Type getResultType(Validator validator, Exp[] args) {
035            return TypeUtil.computeCommonType(
036                true, args[1].getType(), args[2].getType());
037        }
038    
039        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
040            final BooleanCalc booleanCalc =
041                compiler.compileBoolean(call.getArg(0));
042            final Calc calc1 =
043                compiler.compileAs(
044                    call.getArg(1), call.getType(), ResultStyle.ANY_LIST);
045            final Calc calc2 =
046                compiler.compileAs(
047                    call.getArg(2), call.getType(), ResultStyle.ANY_LIST);
048            return new GenericCalc(call) {
049                public Object evaluate(Evaluator evaluator) {
050                    final boolean b =
051                        booleanCalc.evaluateBoolean(evaluator);
052                    Calc calc = b ? calc1 : calc2;
053                    return calc.evaluate(evaluator);
054                }
055    
056                public Calc[] getCalcs() {
057                    return new Calc[] {booleanCalc, calc1, calc2};
058                }
059            };
060        }
061    
062        // IIf(<Logical Expression>, <String Expression>, <String Expression>)
063        static final FunDefBase STRING_INSTANCE = new FunDefBase(
064            "IIf",
065            "Returns one of two string values determined by a logical test.",
066            "fSbSS")
067        {
068            public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
069                final BooleanCalc booleanCalc =
070                    compiler.compileBoolean(call.getArg(0));
071                final StringCalc calc1 = compiler.compileString(call.getArg(1));
072                final StringCalc calc2 = compiler.compileString(call.getArg(2));
073                return new AbstractStringCalc(
074                    call, new Calc[] {booleanCalc, calc1, calc2}) {
075                    public String evaluateString(Evaluator evaluator) {
076                        final boolean b =
077                            booleanCalc.evaluateBoolean(evaluator);
078                        StringCalc calc = b ? calc1 : calc2;
079                        return calc.evaluateString(evaluator);
080                    }
081                };
082            }
083        };
084    
085        // IIf(<Logical Expression>, <Numeric Expression>, <Numeric Expression>)
086        static final FunDefBase NUMERIC_INSTANCE =
087            new IifFunDef(
088                "IIf",
089                "Returns one of two numeric values determined by a logical test.",
090                "fnbnn")
091            {
092                public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
093                    final BooleanCalc booleanCalc =
094                        compiler.compileBoolean(call.getArg(0));
095                    final Calc calc1 = compiler.compileScalar(call.getArg(1), true);
096                    final Calc calc2 = compiler.compileScalar(call.getArg(2), true);
097                    return new GenericCalc(call) {
098                        public Object evaluate(Evaluator evaluator) {
099                            final boolean b =
100                                booleanCalc.evaluateBoolean(evaluator);
101                            Calc calc = b ? calc1 : calc2;
102                            return calc.evaluate(evaluator);
103                        }
104    
105                        public Calc[] getCalcs() {
106                            return new Calc[] {booleanCalc, calc1, calc2};
107                        }
108                    };
109                }
110            };
111    
112        // IIf(<Logical Expression>, <Tuple Expression>, <Tuple Expression>)
113        static final FunDefBase TUPLE_INSTANCE =
114            new IifFunDef(
115                "IIf",
116                "Returns one of two tuples determined by a logical test.",
117                "ftbtt")
118            {
119                public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
120                    final BooleanCalc booleanCalc =
121                        compiler.compileBoolean(call.getArg(0));
122                    final Calc calc1 = compiler.compileTuple(call.getArg(1));
123                    final Calc calc2 = compiler.compileTuple(call.getArg(2));
124                    return new GenericCalc(call) {
125                        public Object evaluate(Evaluator evaluator) {
126                            final boolean b =
127                                booleanCalc.evaluateBoolean(evaluator);
128                            Calc calc = b ? calc1 : calc2;
129                            return calc.evaluate(evaluator);
130                        }
131    
132                        public Calc[] getCalcs() {
133                            return new Calc[] {booleanCalc, calc1, calc2};
134                        }
135                    };
136                }
137            };
138    
139        // IIf(<Logical Expression>, <Boolean Expression>, <Boolean Expression>)
140        static final FunDefBase BOOLEAN_INSTANCE = new FunDefBase(
141            "IIf",
142            "Returns boolean determined by a logical test.",
143            "fbbbb")
144        {
145            public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
146                final BooleanCalc booleanCalc =
147                    compiler.compileBoolean(call.getArg(0));
148                final BooleanCalc booleanCalc1 =
149                    compiler.compileBoolean(call.getArg(1));
150                final BooleanCalc booleanCalc2 =
151                    compiler.compileBoolean(call.getArg(2));
152                Calc[] calcs = {booleanCalc, booleanCalc1, booleanCalc2};
153                return new AbstractBooleanCalc(call, calcs) {
154                    public boolean evaluateBoolean(Evaluator evaluator) {
155                        final boolean condition =
156                            booleanCalc.evaluateBoolean(evaluator);
157                        if (condition) {
158                            return booleanCalc1.evaluateBoolean(evaluator);
159                        } else {
160                            return booleanCalc2.evaluateBoolean(evaluator);
161                        }
162                    }
163                };
164            }
165        };
166    
167        // IIf(<Logical Expression>, <Member Expression>, <Member Expression>)
168        static final IifFunDef MEMBER_INSTANCE =
169            new IifFunDef(
170                "IIf",
171                "Returns one of two member values determined by a logical test.",
172                "fmbmm");
173    
174        // IIf(<Logical Expression>, <Level Expression>, <Level Expression>)
175        static final IifFunDef LEVEL_INSTANCE =
176            new IifFunDef(
177                "IIf",
178                "Returns one of two level values determined by a logical test.",
179                "flbll");
180    
181        // IIf(<Logical Expression>, <Hierarchy Expression>, <Hierarchy Expression>)
182        static final IifFunDef HIERARCHY_INSTANCE =
183            new IifFunDef(
184                "IIf",
185                "Returns one of two hierarchy values determined by a logical test.",
186                "fhbhh");
187    
188        // IIf(<Logical Expression>, <Dimension Expression>, <Dimension Expression>)
189        static final IifFunDef DIMENSION_INSTANCE =
190            new IifFunDef(
191                "IIf",
192                "Returns one of two dimension values determined by a logical test.",
193                "fdbdd");
194    
195        // IIf(<Logical Expression>, <Set Expression>, <Set Expression>)
196        static final IifFunDef SET_INSTANCE =
197            new IifFunDef(
198                "IIf",
199                "Returns one of two set values determined by a logical test.",
200                "fxbxx");
201    }
202    
203    // End IifFunDef.java