001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/fun/CountFunDef.java#7 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2006-2008 Julian Hyde 007 // All Rights Reserved. 008 // You must accept the terms of that agreement to use this software. 009 */ 010 package mondrian.olap.fun; 011 012 import mondrian.olap.FunDef; 013 import mondrian.olap.Literal; 014 import mondrian.olap.Evaluator; 015 import mondrian.olap.Dimension; 016 import mondrian.calc.*; 017 import mondrian.calc.impl.AbstractIntegerCalc; 018 import mondrian.mdx.ResolvedFunCall; 019 020 import java.util.List; 021 022 /** 023 * Definition of the <code>Count</code> MDX function. 024 * 025 * @author jhyde 026 * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/CountFunDef.java#7 $ 027 * @since Mar 23, 2006 028 */ 029 class CountFunDef extends AbstractAggregateFunDef { 030 static final String[] ReservedWords = new String[] {"INCLUDEEMPTY", "EXCLUDEEMPTY"}; 031 032 static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver( 033 "Count", 034 "Count(<Set>[, EXCLUDEEMPTY | INCLUDEEMPTY])", 035 "Returns the number of tuples in a set, empty cells included unless the optional EXCLUDEEMPTY flag is used.", 036 new String[]{"fnx", "fnxy"}, 037 CountFunDef.class, 038 ReservedWords); 039 040 public CountFunDef(FunDef dummyFunDef) { 041 super(dummyFunDef); 042 } 043 044 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 045 final Calc calc = 046 compiler.compileAs( 047 call.getArg(0), null, ResultStyle.ITERABLE_ANY); 048 final boolean includeEmpty = 049 call.getArgCount() < 2 || 050 ((Literal) call.getArg(1)).getValue().equals( 051 "INCLUDEEMPTY"); 052 return new AbstractIntegerCalc( 053 call, new Calc[] {calc}) { 054 public int evaluateInteger(Evaluator evaluator) { 055 /* 056 if (calc instanceof ListCalc) { 057 ListCalc listCalc = (ListCalc) calc; 058 List memberList = evaluateCurrentList(listCalc, evaluator); 059 return count(evaluator, memberList, includeEmpty); 060 } else { 061 // must be IterCalc 062 IterCalc iterCalc = (IterCalc) calc; 063 Iterable iterable = 064 evaluateCurrentIterable(iterCalc, evaluator); 065 return count(evaluator, iterable, includeEmpty); 066 } 067 */ 068 if (calc instanceof IterCalc) { 069 IterCalc iterCalc = (IterCalc) calc; 070 Iterable iterable = 071 evaluateCurrentIterable(iterCalc, evaluator); 072 return count(evaluator, iterable, includeEmpty); 073 } else { 074 // must be ListCalc 075 ListCalc listCalc = (ListCalc) calc; 076 List memberList = evaluateCurrentList(listCalc, evaluator); 077 return count(evaluator, memberList, includeEmpty); 078 } 079 } 080 081 public boolean dependsOn(Dimension dimension) { 082 // COUNT(<set>, INCLUDEEMPTY) is straightforward -- it 083 // depends only on the dimensions that <Set> depends 084 // on. 085 if (super.dependsOn(dimension)) { 086 return true; 087 } 088 if (includeEmpty) { 089 return false; 090 } 091 // COUNT(<set>, EXCLUDEEMPTY) depends only on the 092 // dimensions that <Set> depends on, plus all 093 // dimensions not masked by the set. 094 return ! calc.getType().usesDimension(dimension, true); 095 } 096 }; 097 098 /* 099 RME OLD STUFF 100 final ListCalc memberListCalc = 101 compiler.compileList(call.getArg(0)); 102 final boolean includeEmpty = 103 call.getArgCount() < 2 || 104 ((Literal) call.getArg(1)).getValue().equals( 105 "INCLUDEEMPTY"); 106 return new AbstractIntegerCalc( 107 call, new Calc[] {memberListCalc}) { 108 public int evaluateInteger(Evaluator evaluator) { 109 List memberList = 110 evaluateCurrentList(memberListCalc, evaluator); 111 return count(evaluator, memberList, includeEmpty); 112 } 113 114 public boolean dependsOn(Dimension dimension) { 115 // COUNT(<set>, INCLUDEEMPTY) is straightforward -- it 116 // depends only on the dimensions that <Set> depends 117 // on. 118 if (super.dependsOn(dimension)) { 119 return true; 120 } 121 if (includeEmpty) { 122 return false; 123 } 124 // COUNT(<set>, EXCLUDEEMPTY) depends only on the 125 // dimensions that <Set> depends on, plus all 126 // dimensions not masked by the set. 127 if (memberListCalc.getType().usesDimension(dimension, true)) { 128 return false; 129 } 130 return true; 131 } 132 }; 133 */ 134 } 135 } 136 137 // End CountFunDef.java