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