1 10 package mondrian.olap.fun; 11 12 import mondrian.olap.*; 13 import mondrian.calc.*; 14 import mondrian.calc.impl.GenericCalc; 15 import mondrian.mdx.ResolvedFunCall; 16 17 26 public class CoalesceEmptyFunDef extends FunDefBase { 27 static final ResolverBase Resolver = new ResolverImpl(); 28 29 public CoalesceEmptyFunDef(ResolverBase resolverBase, int type, int[] types) { 30 super(resolverBase, type, types); 31 } 32 33 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 34 final Exp[] args = call.getArgs(); 35 final Calc[] calcs = new Calc[args.length]; 36 for (int i = 0; i < args.length; i++) { 37 calcs[i] = compiler.compileScalar(args[i], true); 38 } 39 return new GenericCalc(call) { 40 public Object evaluate(Evaluator evaluator) { 41 for (Calc calc : calcs) { 42 final Object o = calc.evaluate(evaluator); 43 if (o != null) { 44 return o; 45 } 46 } 47 return null; 48 } 49 50 public Calc[] getCalcs() { 51 return calcs; 52 } 53 }; 54 } 55 56 private static class ResolverImpl extends ResolverBase { 57 public ResolverImpl() { 58 super( 59 "CoalesceEmpty", 60 "CoalesceEmpty(<Value Expression>[, <Value Expression>...])", 61 "Coalesces an empty cell value to a different value. All of the expressions must be of the same type (number or string).", 62 Syntax.Function); 63 } 64 65 public FunDef resolve( 66 Exp[] args, Validator validator, int[] conversionCount) { 67 if (args.length < 1) { 68 return null; 69 } 70 final int[] types = {Category.Numeric, Category.String}; 71 final int[] argTypes = new int[args.length]; 72 for (int type : types) { 73 int matchingArgs = 0; 74 conversionCount[0] = 0; 75 for (int i = 0; i < args.length; i++) { 76 if (validator.canConvert(args[i], type, conversionCount)) { 77 matchingArgs++; 78 } 79 argTypes[i] = type; 80 } 81 if (matchingArgs == args.length) { 82 return new CoalesceEmptyFunDef(this, type, argTypes); 83 } 84 } 85 return null; 86 } 87 88 public boolean requiresExpression(int k) { 89 return true; 90 } 91 } 92 } 93 94 | Popular Tags |