/*
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// You must accept the terms of that agreement to use this software.
//
// Copyright (C) 2004-2005 Julian Hyde
// Copyright (C) 2005-2011 Pentaho and others
// All Rights Reserved.
*/
package mondrian.olap.fun;
import mondrian.calc.Calc;
import mondrian.calc.ExpCompiler;
import mondrian.calc.impl.GenericCalc;
import mondrian.mdx.ResolvedFunCall;
import mondrian.olap.*;
import java.util.List;
/**
* Definition of the <code>CoalesceEmpty</code> MDX function.
*
* <p>It evaluates each of the arguments to the function, returning the
* first such argument that does not return a null value.
*
* @author gjohnson
*/
public class CoalesceEmptyFunDef extends FunDefBase {
static final ResolverBase Resolver = new ResolverImpl();
public CoalesceEmptyFunDef(ResolverBase resolverBase, int type, int[] types)
{
super(resolverBase, type, types);
}
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final Exp[] args = call.getArgs();
final Calc[] calcs = new Calc[args.length];
for (int i = 0; i < args.length; i++) {
calcs[i] = compiler.compileScalar(args[i], true);
}
return new GenericCalc(call) {
public Object evaluate(Evaluator evaluator) {
for (Calc calc : calcs) {
final Object o = calc.evaluate(evaluator);
if (o != null) {
return o;
}
}
return null;
}
public Calc[] getCalcs() {
return calcs;
}
};
}
private static class ResolverImpl extends ResolverBase {
public ResolverImpl() {
super(
"CoalesceEmpty",
"CoalesceEmpty(<Value Expression>[, <Value Expression>...])",
"Coalesces an empty cell value to a different value. All of the expressions must be of the same type (number or string).",
Syntax.Function);
}
public FunDef resolve(
Exp[] args,
Validator validator,
List<Conversion> conversions)
{
if (args.length < 1) {
return null;
}
final int[] types = {Category.Numeric, Category.String};
final int[] argTypes = new int[args.length];
for (int type : types) {
int matchingArgs = 0;
conversions.clear();
for (int i = 0; i < args.length; i++) {
if (validator.canConvert(i, args[i], type, conversions)) {
matchingArgs++;
}
argTypes[i] = type;
}
if (matchingArgs == args.length) {
return new CoalesceEmptyFunDef(this, type, argTypes);
}
}
return null;
}
public boolean requiresExpression(int k) {
return true;
}
}
}
// End CoalesceEmptyFunDef.java