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.impl.ConstantCalc; 16 import mondrian.calc.impl.AbstractCalc; 17 import mondrian.mdx.ResolvedFunCall; 18 19 import java.util.List ; 20 import java.util.ArrayList ; 21 22 37 class CaseMatchFunDef extends FunDefBase { 38 static final ResolverImpl Resolver = new ResolverImpl(); 39 40 private CaseMatchFunDef(FunDef dummyFunDef) { 41 super(dummyFunDef); 42 } 43 44 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 45 final Exp[] args = call.getArgs(); 46 final List <Calc> calcList = new ArrayList <Calc>(); 47 final Calc valueCalc = 48 compiler.compileScalar(args[0], true); 49 calcList.add(valueCalc); 50 final int matchCount = (args.length - 1) / 2; 51 final Calc[] matchCalcs = new Calc[matchCount]; 52 final Calc[] exprCalcs = new Calc[matchCount]; 53 for (int i = 0, j = 1; i < exprCalcs.length; i++) { 54 matchCalcs[i] = 55 compiler.compileScalar(args[j++], true); 56 calcList.add(matchCalcs[i]); 57 exprCalcs[i] = 58 compiler.compileScalar(args[j++], true); 59 calcList.add(exprCalcs[i]); 60 } 61 final Calc defaultCalc = 62 args.length % 2 == 0 ? 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 71 Object value = valueCalc.evaluate(evaluator); 72 for (int i = 0; i < matchCalcs.length; i++) { 73 Object match = matchCalcs[i].evaluate(evaluator); 74 if (match.equals(value)) { 75 return exprCalcs[i].evaluate(evaluator); 76 } 77 } 78 return defaultCalc.evaluate(evaluator); 79 } 80 81 public Calc[] getCalcs() { 82 return calcs; 83 } 84 }; 85 } 86 87 private static class ResolverImpl extends ResolverBase { 88 private ResolverImpl() { 89 super( 90 "_CaseMatch", 91 "Case <Expression> When <Expression> Then <Expression> [...] [Else <Expression>] End", 92 "Evaluates various expressions, and returns the corresponding expression for the first which matches a particular value.", 93 Syntax.Case); 94 } 95 96 public FunDef resolve( 97 Exp[] args, Validator validator, int[] conversionCount) { 98 if (args.length < 3) { 99 return null; 100 } 101 int valueType = args[0].getCategory(); 102 int returnType = args[2].getCategory(); 103 int j = 0; 104 int clauseCount = (args.length - 1) / 2; 105 int mismatchingArgs = 0; 106 if (!validator.canConvert(args[j++], valueType, conversionCount)) { 107 mismatchingArgs++; 108 } 109 for (int i = 0; i < clauseCount; i++) { 110 if (!validator.canConvert(args[j++], valueType, conversionCount)) { 111 mismatchingArgs++; 112 } 113 if (!validator.canConvert(args[j++], returnType, conversionCount)) { 114 mismatchingArgs++; 115 } 116 } 117 if (j < args.length) { 118 if (!validator.canConvert(args[j++], returnType, conversionCount)) { 119 mismatchingArgs++; 120 } 121 } 122 Util.assertTrue(j == args.length); 123 if (mismatchingArgs != 0) { 124 return null; 125 } 126 127 FunDef dummy = createDummyFunDef(this, returnType, args); 128 return new CaseMatchFunDef(dummy); 129 } 130 131 public boolean requiresExpression(int k) { 132 return true; 133 } 134 } 135 } 136 137 | Popular Tags |