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) 2004-2005 Julian Hyde 008// Copyright (C) 2005-2011 Pentaho and others 009// All Rights Reserved. 010*/ 011package mondrian.olap.fun; 012 013import mondrian.calc.Calc; 014import mondrian.calc.ExpCompiler; 015import mondrian.calc.impl.GenericCalc; 016import mondrian.mdx.ResolvedFunCall; 017import mondrian.olap.*; 018 019import java.util.List; 020 021/** 022 * Definition of the <code>CoalesceEmpty</code> MDX function. 023 * 024 * <p>It evaluates each of the arguments to the function, returning the 025 * first such argument that does not return a null value. 026 * 027 * @author gjohnson 028 */ 029public class CoalesceEmptyFunDef extends FunDefBase { 030 static final ResolverBase Resolver = new ResolverImpl(); 031 032 public CoalesceEmptyFunDef(ResolverBase resolverBase, int type, int[] types) 033 { 034 super(resolverBase, type, types); 035 } 036 037 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 038 final Exp[] args = call.getArgs(); 039 final Calc[] calcs = new Calc[args.length]; 040 for (int i = 0; i < args.length; i++) { 041 calcs[i] = compiler.compileScalar(args[i], true); 042 } 043 return new GenericCalc(call) { 044 public Object evaluate(Evaluator evaluator) { 045 for (Calc calc : calcs) { 046 final Object o = calc.evaluate(evaluator); 047 if (o != null) { 048 return o; 049 } 050 } 051 return null; 052 } 053 054 public Calc[] getCalcs() { 055 return calcs; 056 } 057 }; 058 } 059 060 private static class ResolverImpl extends ResolverBase { 061 public ResolverImpl() { 062 super( 063 "CoalesceEmpty", 064 "CoalesceEmpty(<Value Expression>[, <Value Expression>...])", 065 "Coalesces an empty cell value to a different value. All of the expressions must be of the same type (number or string).", 066 Syntax.Function); 067 } 068 069 public FunDef resolve( 070 Exp[] args, 071 Validator validator, 072 List<Conversion> conversions) 073 { 074 if (args.length < 1) { 075 return null; 076 } 077 final int[] types = {Category.Numeric, Category.String}; 078 final int[] argTypes = new int[args.length]; 079 for (int type : types) { 080 int matchingArgs = 0; 081 conversions.clear(); 082 for (int i = 0; i < args.length; i++) { 083 if (validator.canConvert(i, args[i], type, conversions)) { 084 matchingArgs++; 085 } 086 argTypes[i] = type; 087 } 088 if (matchingArgs == args.length) { 089 return new CoalesceEmptyFunDef(this, type, argTypes); 090 } 091 } 092 return null; 093 } 094 095 public boolean requiresExpression(int k) { 096 return true; 097 } 098 } 099} 100 101// End CoalesceEmptyFunDef.java