use of mondrian.olap.fun.Resolver in project mondrian by pentaho.
the class Util method createSimpleValidator.
/**
* Creates a very simple implementation of {@link Validator}. (Only
* useful for resolving trivial expressions.)
*/
public static Validator createSimpleValidator(final FunTable funTable) {
return new Validator() {
public Query getQuery() {
return null;
}
public SchemaReader getSchemaReader() {
throw new UnsupportedOperationException();
}
public Exp validate(Exp exp, boolean scalar) {
return exp;
}
public void validate(ParameterExpr parameterExpr) {
}
public void validate(MemberProperty memberProperty) {
}
public void validate(QueryAxis axis) {
}
public void validate(Formula formula) {
}
public FunDef getDef(Exp[] args, String name, Syntax syntax) {
// Very simple resolution. Assumes that there is precisely
// one resolver (i.e. no overloading) and no argument
// conversions are necessary.
List<Resolver> resolvers = funTable.getResolvers(name, syntax);
final Resolver resolver = resolvers.get(0);
final List<Resolver.Conversion> conversionList = new ArrayList<Resolver.Conversion>();
final FunDef def = resolver.resolve(args, this, conversionList);
assert conversionList.isEmpty();
return def;
}
public boolean alwaysResolveFunDef() {
return false;
}
public boolean canConvert(int ordinal, Exp fromExp, int to, List<Resolver.Conversion> conversions) {
return true;
}
public boolean requiresExpression() {
return false;
}
public FunTable getFunTable() {
return funTable;
}
public Parameter createOrLookupParam(boolean definition, String name, Type type, Exp defaultExp, String description) {
return null;
}
};
}
use of mondrian.olap.fun.Resolver in project mondrian by pentaho.
the class ValidatorImpl method getDef.
public FunDef getDef(Exp[] args, String funName, Syntax syntax) {
// Compute signature first. It makes debugging easier.
final String signature = syntax.getSignature(funName, Category.Unknown, ExpBase.getTypes(args));
// Resolve function by its upper-case name first. If there is only one
// function with that name, stop immediately. If there is more than
// function, use some custom method, which generally involves looking
// at the type of one of its arguments.
List<Resolver> resolvers = funTable.getResolvers(funName, syntax);
assert resolvers != null;
final List<Resolver.Conversion> conversionList = new ArrayList<Resolver.Conversion>();
int minConversionCost = Integer.MAX_VALUE;
List<FunDef> matchDefs = new ArrayList<FunDef>();
List<Resolver.Conversion> matchConversionList = null;
for (Resolver resolver : resolvers) {
conversionList.clear();
FunDef def = resolver.resolve(args, this, conversionList);
if (def != null) {
int conversionCost = sumConversionCost(conversionList);
if (conversionCost < minConversionCost) {
minConversionCost = conversionCost;
matchDefs.clear();
matchDefs.add(def);
matchConversionList = new ArrayList<Resolver.Conversion>(conversionList);
} else if (conversionCost == minConversionCost) {
matchDefs.add(def);
} else {
// ignore this match -- it required more coercions than
// other overloadings we've seen
}
}
}
switch(matchDefs.size()) {
case 0:
throw MondrianResource.instance().NoFunctionMatchesSignature.ex(signature);
case 1:
break;
default:
final StringBuilder buf = new StringBuilder();
for (FunDef matchDef : matchDefs) {
if (buf.length() > 0) {
buf.append(", ");
}
buf.append(matchDef.getSignature());
}
throw MondrianResource.instance().MoreThanOneFunctionMatchesSignature.ex(signature, buf.toString());
}
final FunDef matchDef = matchDefs.get(0);
for (Resolver.Conversion conversion : matchConversionList) {
conversion.checkValid();
conversion.apply(this, Arrays.asList(args));
}
return matchDef;
}