1 10 package mondrian.olap.fun; 11 12 import mondrian.olap.*; 13 import mondrian.calc.Calc; 14 import mondrian.calc.ExpCompiler; 15 import mondrian.calc.BooleanCalc; 16 import mondrian.calc.impl.ConstantCalc; 17 import mondrian.calc.impl.AbstractCalc; 18 import mondrian.mdx.ResolvedFunCall; 19 20 import java.util.List ; 21 import java.util.ArrayList ; 22 23 39 class CaseTestFunDef extends FunDefBase { 40 static final ResolverImpl Resolver = new ResolverImpl(); 41 42 public CaseTestFunDef(FunDef dummyFunDef) { 43 super(dummyFunDef); 44 } 45 46 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 47 final Exp[] args = call.getArgs(); 48 final BooleanCalc[] conditionCalcs = 49 new BooleanCalc[args.length / 2]; 50 final Calc[] exprCalcs = 51 new Calc[args.length / 2]; 52 final List <Calc> calcList = new ArrayList <Calc>(); 53 for (int i = 0, j = 0; i < exprCalcs.length; i++) { 54 conditionCalcs[i] = 55 compiler.compileBoolean(args[j++]); 56 calcList.add(conditionCalcs[i]); 57 exprCalcs[i] = 58 compiler.compileScalar(args[j++], true); 59 calcList.add(exprCalcs[i]); 60 } 61 final Calc defaultCalc = 62 args.length % 2 == 1 ? 63 compiler.compileScalar(args[args.length - 1], true) : 64 ConstantCalc.constantNull(call.getType()); 65 calcList.add(defaultCalc); 66 final Calc[] calcs = calcList.toArray(new Calc[calcList.size()]); 67 68 return new AbstractCalc(call) { 69 public Object evaluate(Evaluator evaluator) { 70 for (int i = 0; i < conditionCalcs.length; i++) { 71 if (conditionCalcs[i].evaluateBoolean(evaluator)) { 72 return exprCalcs[i].evaluate(evaluator); 73 } 74 } 75 return defaultCalc.evaluate(evaluator); 76 } 77 78 public Calc[] getCalcs() { 79 return calcs; 80 } 81 }; 82 } 83 84 private static class ResolverImpl extends ResolverBase { 85 public ResolverImpl() { 86 super( 87 "_CaseTest", 88 "Case When <Logical Expression> Then <Expression> [...] [Else <Expression>] End", 89 "Evaluates various conditions, and returns the corresponding expression for the first which evaluates to true.", 90 Syntax.Case); 91 } 92 93 public FunDef resolve( 94 Exp[] args, Validator validator, int[] conversionCount) { 95 if (args.length < 1) { 96 return null; 97 } 98 int j = 0; 99 int clauseCount = args.length / 2; 100 int mismatchingArgs = 0; 101 int returnType = args[1].getCategory(); 102 for (int i = 0; i < clauseCount; i++) { 103 if (!validator.canConvert(args[j++], Category.Logical, conversionCount)) { 104 mismatchingArgs++; 105 } 106 if (!validator.canConvert(args[j++], returnType, conversionCount)) { 107 mismatchingArgs++; 108 } 109 } 110 if (j < args.length) { 111 if (!validator.canConvert(args[j++], returnType, conversionCount)) { 112 mismatchingArgs++; 113 } 114 } 115 Util.assertTrue(j == args.length); 116 if (mismatchingArgs != 0) { 117 return null; 118 } 119 FunDef dummy = createDummyFunDef(this, returnType, args); 120 return new CaseTestFunDef(dummy); 121 } 122 123 public boolean requiresExpression(int k) { 124 return true; 125 } 126 } 127 } 128 129 | Popular Tags |