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) 2009-2011 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.olap.fun; 011 012import mondrian.calc.*; 013import mondrian.calc.impl.AbstractIterCalc; 014import mondrian.mdx.NamedSetExpr; 015import mondrian.mdx.ResolvedFunCall; 016import mondrian.olap.*; 017 018import java.util.List; 019 020 021/** 022 * Definition of the <code>AS</code> MDX operator. 023 * 024 * <p>Using <code>AS</code>, you can define an alias for an MDX expression 025 * anywhere it appears in a query, and use that alias as you would a calculated 026 * yet. 027 * 028 * @author jhyde 029 * @since Oct 7, 2009 030 */ 031class AsFunDef extends FunDefBase { 032 public static final Resolver RESOLVER = new ResolverImpl(); 033 private final Query.ScopedNamedSet scopedNamedSet; 034 035 /** 036 * Creates an AsFunDef. 037 * 038 * @param scopedNamedSet Named set definition 039 */ 040 private AsFunDef(Query.ScopedNamedSet scopedNamedSet) { 041 super( 042 "AS", 043 "<Expression> AS <Name>", 044 "Assigns an alias to an expression", 045 "ixxn"); 046 this.scopedNamedSet = scopedNamedSet; 047 } 048 049 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 050 // Argument 0, the definition of the set, has been resolved since the 051 // scoped named set was created. Implicit conversions, like converting 052 // a member to a set, have been performed. Use the new expression. 053 scopedNamedSet.setExp(call.getArg(0)); 054 055 return new AbstractIterCalc(call, new Calc[0]) { 056 public TupleIterable evaluateIterable( 057 Evaluator evaluator) 058 { 059 final Evaluator.NamedSetEvaluator namedSetEvaluator = 060 evaluator.getNamedSetEvaluator(scopedNamedSet, false); 061 return namedSetEvaluator.evaluateTupleIterable(evaluator); 062 } 063 }; 064 } 065 066 private static class ResolverImpl extends ResolverBase { 067 public ResolverImpl() { 068 super("AS", null, null, Syntax.Infix); 069 } 070 071 public FunDef resolve( 072 Exp[] args, 073 Validator validator, 074 List<Conversion> conversions) 075 { 076 final Exp exp = args[0]; 077 if (!validator.canConvert( 078 0, args[0], Category.Set, conversions)) 079 { 080 return null; 081 } 082 083 // By the time resolve is called, the id argument has already been 084 // resolved... to a named set, namely itself. That's not pretty. 085 // We'd rather it stayed as an id, and we'd rather that a named set 086 // was not visible in the scope that defines it. But we can work 087 // with this. 088 final String name = 089 ((NamedSetExpr) args[1]).getNamedSet().getName(); 090 091 final Query.ScopedNamedSet scopedNamedSet = 092 (Query.ScopedNamedSet) ((NamedSetExpr) args[1]).getNamedSet(); 093// validator.getQuery().createScopedNamedSet( 094// name, (QueryPart) exp, exp); 095 return new AsFunDef(scopedNamedSet); 096 } 097 } 098} 099 100// End AsFunDef.java