001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/fun/CacheFunDef.java#9 $ 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) 2005-2007 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.olap.type.Type; 014 import mondrian.olap.type.SetType; 015 import mondrian.calc.*; 016 import mondrian.calc.impl.GenericCalc; 017 import mondrian.mdx.ResolvedFunCall; 018 019 import java.io.PrintWriter; 020 021 /** 022 * Definition of the <code>Cache</code> system function, which is smart enough 023 * to evaluate its argument only once. 024 * 025 * @author jhyde 026 * @since 2005/8/14 027 * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/CacheFunDef.java#9 $ 028 */ 029 public class CacheFunDef extends FunDefBase { 030 static final String NAME = "Cache"; 031 private static final String SIGNATURE = "Cache(<<Exp>>)"; 032 private static final String DESCRIPTION = "Evaluates and returns its sole argument, applying statement-level caching"; 033 private static final Syntax SYNTAX = Syntax.Function; 034 static final CacheFunResolver Resolver = new CacheFunResolver(); 035 036 CacheFunDef( 037 String name, 038 String signature, 039 String description, 040 Syntax syntax, 041 int category, 042 Type type) { 043 super(name, signature, description, syntax, 044 category, new int[] {category}); 045 Util.discard(type); 046 } 047 048 public void unparse(Exp[] args, PrintWriter pw) { 049 args[0].unparse(pw); 050 } 051 052 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 053 final Exp exp = call.getArg(0); 054 final ExpCacheDescriptor cacheDescriptor = 055 new ExpCacheDescriptor(exp, compiler); 056 return new GenericCalc(call) { 057 public Object evaluate(Evaluator evaluator) { 058 return evaluator.getCachedResult(cacheDescriptor); 059 } 060 061 public Calc[] getCalcs() { 062 return new Calc[] {cacheDescriptor.getCalc()}; 063 } 064 065 public ResultStyle getResultStyle() { 066 // cached lists are immutable 067 if (type instanceof SetType) { 068 return ResultStyle.LIST; 069 } else { 070 return ResultStyle.VALUE; 071 } 072 } 073 }; 074 } 075 076 public static class CacheFunResolver extends ResolverBase { 077 CacheFunResolver() { 078 super(NAME, SIGNATURE, DESCRIPTION, SYNTAX); 079 } 080 081 public FunDef resolve( 082 Exp[] args, Validator validator, int[] conversionCount) { 083 if (args.length != 1) { 084 return null; 085 } 086 final Exp exp = args[0]; 087 final int category = exp.getCategory(); 088 final Type type = exp.getType(); 089 return new CacheFunDef(NAME, SIGNATURE, DESCRIPTION, SYNTAX, 090 category, type); 091 } 092 093 public boolean requiresExpression(int k) { 094 return false; 095 } 096 } 097 } 098 099 // End CacheFunDef.java