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