1 11 package mondrian.olap.fun; 12 13 import mondrian.calc.Calc; 14 import mondrian.calc.ExpCompiler; 15 import mondrian.calc.IntegerCalc; 16 import mondrian.calc.ListCalc; 17 import mondrian.calc.impl.AbstractListCalc; 18 import mondrian.calc.ExpCompiler.ResultStyle; 19 import mondrian.mdx.ResolvedFunCall; 20 import mondrian.olap.*; 21 import mondrian.olap.type.TupleType; 22 23 import java.util.List ; 24 25 33 class TopBottomCountFunDef extends FunDefBase { 34 boolean top; 35 36 static final MultiResolver TopCountResolver = new MultiResolver( 37 "TopCount", 38 "TopCount(<Set>, <Count>[, <Numeric Expression>])", 39 "Returns a specified number of items from the top of a set, optionally ordering the set first.", 40 new String []{"fxxnn", "fxxn"}) { 41 protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) { 42 return new TopBottomCountFunDef(dummyFunDef, true); 43 } 44 }; 45 46 static final MultiResolver BottomCountResolver = new MultiResolver( 47 "BottomCount", 48 "BottomCount(<Set>, <Count>[, <Numeric Expression>])", 49 "Returns a specified number of items from the bottom of a set, optionally ordering the set first.", 50 new String []{"fxxnn", "fxxn"}) { 51 protected FunDef createFunDef(Exp[] args, FunDef dummyFunDef) { 52 return new TopBottomCountFunDef(dummyFunDef, false); 53 } 54 }; 55 56 public TopBottomCountFunDef(FunDef dummyFunDef, final boolean top) { 57 super(dummyFunDef); 58 this.top = top; 59 } 60 61 public Calc compileCall(final ResolvedFunCall call, ExpCompiler compiler) { 62 final ListCalc listCalc = 65 compiler.compileList(call.getArg(0), true); 66 final IntegerCalc integerCalc = 67 compiler.compileInteger(call.getArg(1)); 68 final Calc orderCalc = 69 call.getArgCount() > 2 ? 70 compiler.compileScalar(call.getArg(2), true) : 71 null; 72 final int arity = call.getType() instanceof TupleType ? 73 ((TupleType) call.getType()).elementTypes.length : 74 1; 75 return new AbstractListCalc(call, new Calc[] {listCalc, integerCalc, orderCalc}) { 76 public List evaluateList(Evaluator evaluator) { 77 SchemaReader schemaReader = evaluator.getSchemaReader(); 80 NativeEvaluator nativeEvaluator = 81 schemaReader.getNativeSetEvaluator( 82 call.getFunDef(), call.getArgs(), evaluator, this); 83 if (nativeEvaluator != null) { 84 return (List ) nativeEvaluator.execute(ResultStyle.LIST); 85 } 86 87 List list = listCalc.evaluateList(evaluator); 88 int n = integerCalc.evaluateInteger(evaluator); 89 if (n == mondrian.olap.fun.FunUtil.IntegerNull) { 91 return new java.util.ArrayList (); 92 } 93 if (orderCalc != null) { 94 if (arity == 1) { 95 sortMembers( 96 evaluator.push(), 97 (List <Member>) list, 98 orderCalc, top, true); 99 } else { 100 sortTuples( 101 evaluator.push(), 102 (List <mondrian.olap.Member[]>) list, 103 orderCalc, top, true, arity); 104 } 105 } 106 if (n < list.size()) { 107 list = list.subList(0, n); 108 } 109 return list; 110 } 111 112 public boolean dependsOn(Dimension dimension) { 113 return anyDependsButFirst(getCalcs(), dimension); 114 } 115 }; 116 } 117 } 118 119 | Popular Tags |