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.ExpCompiler.ResultStyle; 16 import mondrian.calc.ListCalc; 17 import mondrian.calc.IterCalc; 18 import mondrian.calc.impl.ValueCalc; 19 import mondrian.calc.impl.AbstractDoubleCalc; 20 import mondrian.mdx.ResolvedFunCall; 21 22 import java.util.List ; 23 24 31 class SumFunDef extends AbstractAggregateFunDef { 32 static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver( 33 "Sum", 34 "Sum(<Set>[, <Numeric Expression>])", 35 "Returns the sum of a numeric expression evaluated over a set.", 36 new String []{"fnx", "fnxn"}, 37 SumFunDef.class); 38 39 public SumFunDef(FunDef dummyFunDef) { 40 super(dummyFunDef); 41 } 42 43 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 44 ResultStyle[] rs = compiler.getAcceptableResultStyles(); 45 for (int i = 0; i < rs.length; i++) { 47 switch (rs[i]) { 48 case ITERABLE : 49 case ANY : 50 return compileCall(call, compiler, ResultStyle.ITERABLE); 53 case MUTABLE_LIST: 54 return compileCall(call, compiler, ResultStyle.MUTABLE_LIST); 56 case LIST : 57 return compileCall(call, compiler, ResultStyle.LIST); 60 } 61 } 62 throw ResultStyleException.generate( 63 new ResultStyle[] { 64 ResultStyle.ITERABLE, 65 ResultStyle.LIST, 66 ResultStyle.MUTABLE_LIST, 67 ResultStyle.ANY 68 }, 69 rs 70 ); 71 } 72 protected Calc compileCall(final ResolvedFunCall call, 73 ExpCompiler compiler, ResultStyle resultStyle) { 74 final Calc ncalc = compiler.compile(call.getArg(0), 75 new ResultStyle[] { resultStyle}); 76 final Calc calc = call.getArgCount() > 1 ? 77 compiler.compileScalar(call.getArg(1), true) : 78 new ValueCalc(call); 79 if (ncalc instanceof ListCalc) { 81 return genListCalc(call, ncalc, calc); 82 } else { 83 return genIterCalc(call, ncalc, calc); 84 } 85 } 86 protected Calc genIterCalc(final ResolvedFunCall call, 87 final Calc ncalc, final Calc calc) { 88 return new AbstractDoubleCalc(call, new Calc[] {ncalc, calc}) { 89 public double evaluateDouble(Evaluator evaluator) { 90 IterCalc iterCalc = (IterCalc) ncalc; 91 Iterable iterable = 92 evaluateCurrentIterable(iterCalc, evaluator); 93 return sumDouble(evaluator.push(), iterable, calc); 94 } 95 96 public Calc[] getCalcs() { 97 return new Calc[] {ncalc, calc}; 98 } 99 100 public boolean dependsOn(Dimension dimension) { 101 return anyDependsButFirst(getCalcs(), dimension); 102 } 103 }; 104 } 105 106 protected Calc genListCalc(final ResolvedFunCall call, 107 final Calc ncalc, final Calc calc) { 108 return new AbstractDoubleCalc(call, new Calc[] {ncalc, calc}) { 109 public double evaluateDouble(Evaluator evaluator) { 110 ListCalc listCalc = (ListCalc) ncalc; 111 List memberList = evaluateCurrentList(listCalc, evaluator); 112 return sumDouble(evaluator.push(), memberList, calc); 113 } 114 115 public Calc[] getCalcs() { 116 return new Calc[] {ncalc, calc}; 117 } 118 119 public boolean dependsOn(Dimension dimension) { 120 return anyDependsButFirst(getCalcs(), dimension); 121 } 122 }; 123 } 124 } 125 126 | Popular Tags |