public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { final Exp[] args = call.getArgs(); final BooleanCalc[] conditionCalcs = new BooleanCalc[args.length / 2]; final Calc[] exprCalcs = new Calc[args.length / 2]; final List<Calc> calcList = new ArrayList<Calc>(); for (int i = 0, j = 0; i < exprCalcs.length; i++) { conditionCalcs[i] = compiler.compileBoolean(args[j++]); calcList.add(conditionCalcs[i]); exprCalcs[i] = compiler.compile(args[j++]); calcList.add(exprCalcs[i]); } final Calc defaultCalc = args.length % 2 == 1 ? compiler.compileScalar(args[args.length - 1], true) : ConstantCalc.constantNull(call.getType()); calcList.add(defaultCalc); final Calc[] calcs = calcList.toArray(new Calc[calcList.size()]); return new GenericCalc(call) { public Object evaluate(Evaluator evaluator) { for (int i = 0; i < conditionCalcs.length; i++) { if (conditionCalcs[i].evaluateBoolean(evaluator)) { return exprCalcs[i].evaluate(evaluator); } } return defaultCalc.evaluate(evaluator); } public Calc[] getCalcs() { return calcs; } }; }
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { final Exp exp = call.getArg(0); final ExpCacheDescriptor cacheDescriptor = new ExpCacheDescriptor(exp, compiler); if (call.getType() instanceof SetType) { return new GenericIterCalc(call) { public Object evaluate(Evaluator evaluator) { return evaluator.getCachedResult(cacheDescriptor); } public Calc[] getCalcs() { return new Calc[] {cacheDescriptor.getCalc()}; } public ResultStyle getResultStyle() { // cached lists are immutable return ResultStyle.LIST; } }; } else { return new GenericCalc(call) { public Object evaluate(Evaluator evaluator) { return evaluator.getCachedResult(cacheDescriptor); } public Calc[] getCalcs() { return new Calc[] {cacheDescriptor.getCalc()}; } public ResultStyle getResultStyle() { return ResultStyle.VALUE; } }; } }
/** * Returns the scenario inside a calculated member in the scenario dimension. For example, applied * to [Scenario].[1], returns the Scenario object representing scenario #1. * * @param member Wrapper member * @return Wrapped scenario */ static Scenario forMember(final RolapMember member) { if (isScenario(member.getHierarchy())) { final Formula formula = ((RolapCalculatedMember) member).getFormula(); final ResolvedFunCall resolvedFunCall = (ResolvedFunCall) formula.getExpression(); final Calc calc = resolvedFunCall.getFunDef().compileCall(null, null); return ((ScenarioCalc) calc).getScenario(); } else { return null; } }
public Calc compileCall(final ResolvedFunCall call, ExpCompiler compiler) { final MemberCalc[] memberCalcs = compileMembers(call.getArg(0), call.getArg(1), compiler); return new AbstractListCalc(call, new Calc[] {memberCalcs[0], memberCalcs[1]}) { public List evaluateList(Evaluator evaluator) { final Member member0 = memberCalcs[0].evaluateMember(evaluator); final Member member1 = memberCalcs[1].evaluateMember(evaluator); if (member0.isNull() || member1.isNull()) { return Collections.EMPTY_LIST; } if (member0.getLevel() != member1.getLevel()) { throw evaluator.newEvalException( call.getFunDef(), "Members must belong to the same level"); } return FunUtil.memberRange(evaluator, member0, member1); } }; }
private boolean requiresExpression(int n) { if (n < 1) { return false; } final Object parent = stack.get(n - 1); if (parent instanceof Formula) { return ((Formula) parent).isMember(); } else if (parent instanceof ResolvedFunCall) { final ResolvedFunCall funCall = (ResolvedFunCall) parent; if (funCall.getFunDef().getSyntax() == Syntax.Parentheses) { return requiresExpression(n - 1); } else { int k = whichArg(funCall, (Exp) stack.get(n)); if (k < 0) { // Arguments of call have mutated since call was placed // on stack. Presumably the call has already been // resolved correctly, so the answer we give here is // irrelevant. return false; } final FunDef funDef = funCall.getFunDef(); final int[] parameterTypes = funDef.getParameterCategories(); return parameterTypes[k] != Category.Set; } } else if (parent instanceof UnresolvedFunCall) { final UnresolvedFunCall funCall = (UnresolvedFunCall) parent; if (funCall.getSyntax() == Syntax.Parentheses || funCall.getFunName().equals("*")) { return requiresExpression(n - 1); } else { int k = whichArg(funCall, (Exp) stack.get(n)); if (k < 0) { // Arguments of call have mutated since call was placed // on stack. Presumably the call has already been // resolved correctly, so the answer we give here is // irrelevant. return false; } return requiresExpression(funCall, k); } } else { return false; } }
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { final MemberCalc memberCalc = compiler.compileMember(call.getArg(0)); final IntegerCalc integerCalc = compiler.compileInteger(call.getArg(1)); final boolean lag = call.getFunName().equals("Lag"); return new AbstractMemberCalc(call, new Calc[] {memberCalc, integerCalc}) { public Member evaluateMember(Evaluator evaluator) { Member member = memberCalc.evaluateMember(evaluator); int n = integerCalc.evaluateInteger(evaluator); if (lag) { if (n == Integer.MIN_VALUE) { // Bump up lagValue by one, otherwise -n (used // in the getLeadMember call below) is out of // range because Integer.MAX_VALUE == // -(Integer.MIN_VALUE + 1). n += 1; } n = -n; } return evaluator.getSchemaReader().getLeadMember(member, n); } }; }